libunicap/0000755000175000017500000000000013164711411013255 5ustar zmoelnigzmoelniglibunicap/configure.ac0000644000175000017500000004222213164711411015545 0ustar zmoelnigzmoelnig# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT([libunicap],[1.0],[arne@unicap-imaging.org]) AM_CONFIG_HEADER(config.h) # 1. Start with version information of `0:0:0' for each libtool library. # 2. Update the version information only immediately before a public release of your software. More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster. # 3. If the library source code has changed at all since the last update, then increment revision (`c:r:a' becomes `c:r+1:a'). # 4. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0. # 5. If any interfaces have been added since the last public release, then increment age. # 6. If any interfaces have been removed since the last public release, then set age to 0. lt_major=4 lt_revision=0 lt_age=2 unicap_major_version=0 unicap_minor_version=9 unicap_micro_version=13 unicap_prerelease= dist_version=$unicap_major_version.$unicap_minor_version.$unicap_micro_version$unicap_prerelease #lt_major - lt_age pkg_version=2 AM_INIT_AUTOMAKE(libunicap, $dist_version) AC_SUBST(lt_major) AC_SUBST(lt_revision) AC_SUBST(lt_age) AC_SUBST(unicap_major_version) AC_SUBST(unicap_minor_version) AC_SUBST(unicap_micro_version) AC_SUBST(dist_version) AC_SUBST(pkg_version) AC_CONFIG_MACRO_DIR(m4) # Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_LIBTOOL AM_PROG_LIBTOOL # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/time.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T AC_HEADER_TIME AC_C_VOLATILE # Checks for library functions. AC_FUNC_CLOSEDIR_VOID AC_PROG_GCC_TRADITIONAL AC_FUNC_MALLOC AC_FUNC_MMAP AC_CHECK_FUNCS([atexit bzero gettimeofday memset munmap strerror strncasecmp strstr]) AM_PROG_CC_C_O # # Intltool # IT_PROG_INTLTOOL([0.35.0]) # # Gettext # GETTEXT_PACKAGE=unicap AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Gettext Package]) AM_GNU_GETTEXT([external]) GTK_DOC_CHECK(1.4) # Check for dl DL_PRESENT="" AC_CHECK_LIB( dl, dlopen, DL_PRESENT="yes",, $DL_LIBS -ldl ) if test "x$DL_PRESENT" = "xyes"; then AC_DEFINE(HAVE_LIBDL, 1, [Define if DL lib is present]) DL_LIBS="-ldl" AC_SUBST(DL_LIBS) fi # Check for libm M_PRESENT="" AC_CHECK_LIB( m, sin, M_PRESENT="yes",, $M_LIBS -lm ) if test "x$M_PRESENT" = "xyes"; then AC_DEFINE(HAVE_LIBM, 1, [Define if libm is present]) M_LIBS="-lm" AC_SUBST(M_LIBS) fi # Check for pthread PTHREAD_PRESENT="" AC_CHECK_LIB( pthread, pthread_create, PTHREAD_PRESENT="yes",, $PTHREAD_LIBS -lpthread ) if test "x$PTHREAD_PRESENT" = "xyes"; then AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if libpthread is present]) PTHREAD_LIBS="-lpthread" AC_SUBST(PTHREAD_LIBS) fi # Check for rt RT_PRESENT="" AC_CHECK_LIB( rt, shm_open, RT_PRESENT="yes",, $RT_LIBS -lrt ) if test "x$RT_PRESENT" = "xyes"; then AC_DEFINE(HAVE_LIBRT, 1, [Define if librt is present]) RT_LIBS="-lrt" AC_SUBST(RT_LIBS) fi # Check for videodev.h ( old v4l support ) AC_CHECK_HEADER (linux/videodev.h, [HAVE_VIDEODEV="yes"],,) # Check for raw1394 pkg_modules="libraw1394 <= 1.0.0" PKG_CHECK_MODULES(LIBRAW1394_PACKAGE, [$pkg_modules], HAVE_LIBRAW1394="yes";LIBRAW1394_VERSION="RAW1394_1_0_API", HAVE_LIBRAW1394="no" ) if( test "x$HAVE_LIBRAW1394" != "xyes" ); then pkg_modules="libraw1394 >= 1.1.0" PKG_CHECK_MODULES(LIBRAW1394_PACKAGE, [$pkg_modules], HAVE_LIBRAW1394="yes";LIBRAW1394_VERSION="RAW1394_1_1_API", HAVE_LIBRAW1394="no" ) if( test "x$HAVE_LIBRAW1394" = "xyes" ); then AC_DEFINE(RAW1394_1_1_API, 1, [Define if using the new raw1394 API]) fi else AC_DEFINE(RAW1394_1_0_API, 1, [Define if using the old raw1394 API]) fi AC_SUBST(LIBRAW1394_PACKAGE_CFLAGS) AC_SUBST(LIBRAW1394_PACKAGE_LIBS) AC_SUBST(LIBRAW1394_VERSION) # Check for aravis PKG_CHECK_MODULES(ARAVIS_PACKAGE, "aravis-0.2", HAVE_ARAVIS="yes", HAVE_ARAVIS="no" ) AC_SUBST(ARAVIS_PACKAGE_CFLAGS) AC_SUBST(ARAVIS_PACKAGE_LIBS) AC_ARG_ENABLE(debug-vid21394, AS_HELP_STRING( [--enable-debug-vid21394], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( VID21394_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( VID21394_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( VID21394_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(vid21394-bootload, AS_HELP_STRING( [--enable-vid21394-bootload], [Enable vid21394 bootload support ( dangerous! )] ), { if test "x$enableval" != "xno"; then AC_DEFINE( VID21394_BOOTLOAD, 1, [Define to enable bootload support] ) else AC_DEFINE( VID21394_BOOTLOAD, 0, [Define to enable bootload support] ) fi }, AC_DEFINE( VID21394_BOOTLOAD, 0, [Define to enable bootload support] ) ) VID21394_VISCA="no" AC_ARG_ENABLE(vid21394-visca, AS_HELP_STRING( [--enable-vid21394-visca], [Enable vid21394 visca protocol support] ), { if test "x$enableval" != "xno"; then AC_DEFINE( VID21394_VISCA, 1, [Define to enable vid21394 visca support] ) VID21394_VISCA="yes" else AC_DEFINE( VID21394_VISCA, 0, [Define to enable vid21394 visca support] ) fi }, AC_DEFINE( VID21394_VISCA, 0, [Define to enable vid21394 visca support] ) ) AM_CONDITIONAL(VID21394_VISCA, test "x$VID21394_VISCA" = xyes ) VID21394_21CF04="no" AC_ARG_ENABLE(vid21394-21cf04, AS_HELP_STRING( [--enable-vid21394-21cf04], [Enable autodetection of DFK 21CF04 camera module ( default=yes )] ), { if test "x$enableval" != "xno"; then AC_DEFINE( VID21394_DETECT_21CF04, 1, [Define to enable autodetection of DFK 21CF04 camera module] ) else AC_DEFINE( VID21394_DETECT_21CF04, 0, [Define to enable autodetection of DFK 21CF04 camera module] ) fi }, AC_DEFINE( VID21394_DETECT_21CF04, 1, [Define to enable autodetection of DFK 21CF04 camera module] ) ) AC_ARG_ENABLE(debug-dcam, AS_HELP_STRING( [--enable-debug-dcam], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( DCAM_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( DCAM_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( DCAM_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(debug-euvccam, AS_HELP_STRING( [--enable-debug-euvccam], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( EUVCCAM_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( EUVCCAM_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( EUVCCAM_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(debug-v4l, AS_HELP_STRING( [--enable-debug-v4l], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( V4L_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( V4L_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( V4L_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(debug-v4l2, AS_HELP_STRING( [--enable-debug-v4l2], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( V4L2_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( V4L2_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( V4L2_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(debug-thing, AS_HELP_STRING( [--enable-debug-thing], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( THING_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( THING_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( THING_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(debug-unicap, AS_HELP_STRING( [--enable-debug-unicap], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( UNICAP_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( UNICAP_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( UNICAP_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(debug-ucil, AS_HELP_STRING( [--enable-debug-ucil], [Enable debug output] ), { if test "x$enableval" != "xno"; then AC_DEFINE( UCIL_DEBUG, 1, [Define to enable debug output] ) else AC_DEFINE( UCIL_DEBUG, 0, [Define to enable debug output] ) fi }, AC_DEFINE( UCIL_DEBUG, 0, [Define to enable debug output] ) ) AC_ARG_ENABLE(vid21394, AS_HELP_STRING( [--enable-vid21394], [build plugin for video-2-1394 capture device \[default=yes\]] ), { if test "x$enableval" != "xno"; then VID21394="yes"; else VID21394="no"; fi }, VID21394="yes" ) if test "$VID21394" = "yes"; then if test "$HAVE_LIBRAW1394" != "yes"; then AC_MSG_RESULT([ video-to-1394 plugin requires recent libraw1394! ]) VID21394="no ( missing libraw1394 )" fi fi if test "x$VID21394" = "xyes"; then AC_DEFINE( BUILD_VID21394, 1, [Define to build vid21394 cpi] ) fi AC_ARG_ENABLE(dcam, AS_HELP_STRING( [--enable-dcam], [build plugin for IIDC 1394 cameras \[default=yes\]] ), { if test "x$enableval" != "xno"; then DCAM="yes"; else DCAM="no"; fi }, DCAM="yes" ) if test "x$DCAM" = "xyes"; then if test "$HAVE_LIBRAW1394" != "yes"; then AC_MSG_RESULT([ IIDC 1394 camera plugin requires recent libraw1394! ]) DCAM="no ( missing libraw1394 )" fi fi if test "x$DCAM" = "xyes"; then AC_DEFINE( BUILD_DCAM, 1, [Define to build dcam cpi] ) fi AC_ARG_ENABLE(v4l, AS_HELP_STRING( [--enable-v4l], [build plugin for video-4-linux ( version 1 ) interface \[default=yes\]] ), { if test "x$enableval" != "xno"; then V4L="yes"; else V4L="no"; fi }, V4L="yes" ) if test "x$V4L" = "xyes"; then if test "$HAVE_VIDEODEV" != "yes"; then AC_MSG_RESULT([ linux/videodev.h not found for (old) v4l support! ]) V4L="no ( missing linux/videodev.h, obsolete video interface )" fi fi if test "x$V4L" = "xyes"; then AC_DEFINE( BUILD_V4L, 1, [Define to build v4l cpi] ) fi AC_ARG_ENABLE(v4l2, AS_HELP_STRING( [--enable-v4l2], [build plugin for video-4-linux ( version 2 ) interface \[default=yes\]] ), { if test "x$enableval" != "xno"; then V4L2="yes"; else V4L2="no"; fi }, V4L2="yes" ) if test "x$V4L2" = "xyes"; then AC_DEFINE( BUILD_V4L2, 1, [Define to build v4l2 cpi] ) fi AC_ARG_ENABLE(libv4l, AS_HELP_STRING( [--enable-libv4l], [use libv4l to communicate with v4l2 devices \[default=no\]] ), { if test "x$enableval" != "xno"; then USE_LIBV4L="yes"; else USE_LIBV4L="no"; fi }, USE_LIBV4L="no" ) if test "x$USE_LIBV4L" = "xyes"; then PKG_CHECK_MODULES(LIBV4L, libv4l2, HAVE_LIBV4L="yes", HAVE_LIBV4L="no") if test "x$HAVE_LIBV4L" = "xyes"; then AC_MSG_RESULT( enable enable enable ) AC_DEFINE( [USE_LIBV4L], 1, Define to enable libv4l support ) else AC_DEFINE( [USE_LIBV4L], 0, Define to enable libv4l support ) fi fi AM_CONDITIONAL(HAVE_LIBV4L, test "x$HAVE_LIBV4L" = "xyes" ) PKG_CHECK_MODULES(LIBUDEV, libudev, HAVE_LIBUDEV="yes", HAVE_LIBUDEV="no") if test "x$HAVE_LIBUDEV" = "xyes"; then AC_DEFINE( [USE_LIBUDEV], 1, Define to enable libudev support ) else AC_DEFINE( [USE_LIBUDEV], 0, Define to enable libudev support ) fi AM_CONDITIONAL(HAVE_LIBUDEV, test x$HAVE_LIBUDEV = "xyes" ) AC_ARG_ENABLE(euvccam, AS_HELP_STRING( [--enable-euvccam], [build plugin for The Imaging Source USB CMOS cameras (experimental) \[default=yes\]] ), { if test "x$enableval" != "xno"; then EUVCCAM="yes"; else EUVCCAM="no"; fi }, EUVCCAM="yes" ) AC_ARG_ENABLE(dcam, AS_HELP_STRING( [--enable-dcam], [build plugin for IIDC 1394 cameras \[default=yes\]] ), { if test "x$enableval" != "xno"; then DCAM="yes"; else DCAM="no"; fi }, DCAM="yes" ) if test "x$DCAM" = "xyes"; then if test "$HAVE_LIBRAW1394" != "yes"; then AC_MSG_RESULT([ IIDC 1394 camera plugin requires recent libraw1394! ]) DCAM="no ( missing libraw1394 )" fi fi if test "x$DCAM" = "xyes"; then AC_DEFINE( BUILD_DCAM, 1, [Define to build dcam cpi] ) fi AC_ARG_ENABLE(aravis, AS_HELP_STRING( [--enable-aravis], [build plugin for cameras supported by aravis \[default=yes\]] ), { if test "x$enabledval" != "xno"; then ARAVIS="yes"; else ARAVIS="no"; fi }, ARAVIS="yes" ) if test "x$ARAVIS" = "xyes"; then if test "$HAVE_ARAVIS" != "yes"; then ARAVIS="no ( missing aravis library )" fi fi if test "x$ARAVIS" = "xyes"; then AC_DEFINE( BUILD_ARAVIS, 1, [Define to build aravis cpi] ) fi AC_ARG_ENABLE(thing, AS_HELP_STRING( [--enable-thing], [build plugin for a dummy device ( usefull for debugging ) \[default=no\]] ), { if test "x$enableval" != "xno"; then THING="yes" THING_SUBDIR="thing" else THING="no"; fi }, THING="no" ) AC_ARG_ENABLE(static-cpi, AS_HELP_STRING( [--enable-static-cpi], [Static link the cpi modules ( default=no )] ), { if test "x$enableval" = "xyes"; then AC_DEFINE( ENABLE_STATIC_CPI, 1, [Define to enable static cpi]) ENABLE_STATIC_CPI="yes"; fi }, ENABLE_STATIC_CPI="no" ) AM_CONDITIONAL(ENABLE_STATIC_CPI, test x$ENABLE_STATIC_CPI = xyes ) AC_ARG_ENABLE(thread-locking, AS_HELP_STRING( [--enable-thread-locking], [ (default=yes) ] ), { if test "x$enableval" = "xyes"; then AC_DEFINE( UNICAP_THREAD_LOCKING, 1, [Define to enable thread locking] ) fi }, AC_DEFINE( UNICAP_THREAD_LOCKING, 1, [Define to enable thread locking] ) ) AC_ARG_ENABLE(unicap-threads, AS_HELP_STRING( [--enable-unicap-threads], [ (default=yes) ] ), { if test "x$enableval" = "xyes"; then AC_DEFINE( UNICAP_THREADS, 1, [Define to enable threads] ) fi }, AC_DEFINE( UNICAP_THREADS, 1, [Define to enable threads] ) ) AM_CONDITIONAL(BUILD_VID21394, test "x$VID21394" = xyes ) AM_CONDITIONAL(BUILD_DCAM, test "x$DCAM" = xyes ) AM_CONDITIONAL(BUILD_V4L, test "x$V4L" = xyes ) AM_CONDITIONAL(BUILD_V4L2, test "x$V4L2" = xyes ) AM_CONDITIONAL(BUILD_EUVCCAM, test "x$EUVCCAM" = xyes) AM_CONDITIONAL(BUILD_ARAVIS, test "x$ARAVIS" = xyes) AM_CONDITIONAL(BUILD_THING, test "x$THING" = xyes ) AC_CONFIG_FILES([ include/unicap_version.h po/Makefile.in include/Makefile src/Makefile common/Makefile ]) AC_CONFIG_FILES([ Makefile libunicap.pc ]) AC_CONFIG_FILES([ cpi/vid21394/Makefile ]) AC_CONFIG_FILES([ cpi/dcam/Makefile ]) AC_CONFIG_FILES([ cpi/v4l/Makefile ]) AC_CONFIG_FILES([ cpi/v4l2cpi/Makefile ]) AC_CONFIG_FILES([ cpi/euvccam/Makefile ]) AC_CONFIG_FILES([ cpi/aravis/Makefile ]) AC_CONFIG_FILES([ cpi/thing/Makefile ]) AC_CONFIG_FILES([ cpi/Makefile cpi/include/Makefile ]) AC_CONFIG_FILES([ doc/libunicap/Makefile doc/Makefile ]) AC_CONFIG_FILES([ data/Makefile ]) AC_OUTPUT if test "x$VID21394_VISCA" = xyes; then VID21394="$VID21394 with visca support" fi if test "x$HAVE_LIBV4L" = xyes && test x$V4L2 = xyes; then V4L2="yes, with libv4l2 support" fi if test "x$HAVE_LIBUDEV" != xyes && test x$V4L2 = xyes; then V4L2+=", libudev is recommended for this module but was not found" fi AC_MSG_RESULT([ ****************************************************** ]) AC_MSG_RESULT([ Unicap $dist_version ]) AC_MSG_RESULT([ ****************************************************** ]) AC_MSG_RESULT([ This software is distributed under the terms and ]) AC_MSG_RESULT([ conditions of the GNU GENERAL PUBLIC LICENSE ( GPL ). ]) AC_MSG_RESULT([ See the file COPYING for the full license text. ]) AC_MSG_RESULT([ ****************************************************** ]) AC_MSG_RESULT([]) AC_MSG_RESULT([Configuration: ]) AC_MSG_RESULT([ libraw1394 version: $LIBRAW1394_VERSION ]) AC_MSG_RESULT([ installation goes to: $prefix ]) #AC_MSG_RESULT([ static cpi: $ENABLE_STATIC_CPI ]) AC_MSG_RESULT([]) AC_MSG_RESULT([Plugins: ]) AC_MSG_RESULT([ video-to-1394: $VID21394 ]) AC_MSG_RESULT([ IIDC 1394 camera: $DCAM ]) AC_MSG_RESULT([ video-4-linux: $V4L ]) AC_MSG_RESULT([ video-4-linux v2: $V4L2 ]) AC_MSG_RESULT([ euvccam: $EUVCCAM ]) AC_MSG_RESULT([ aravis: $ARAVIS ]) AC_MSG_RESULT([]) AC_MSG_RESULT([ ****************************************************** ]) AC_MSG_RESULT([ *** Please read the file README.troubleshooting *** ]) AC_MSG_RESULT([ *** if you have any trouble using this software. *** ]) AC_MSG_RESULT([ ****************************************************** ]) AC_MSG_RESULT([]) libunicap/autogen.sh0000755000175000017500000000476713164711411015274 0ustar zmoelnigzmoelnig#!/bin/sh # # this file is a copy from autotools-dev/examples # # # autogen.sh glue for hplip # # HPLIP used to have five or so different autotools trees. Upstream # has reduced it to two. Still, this script is capable of cleaning # just about any possible mess of autoconf files. # # BE CAREFUL with trees that are not completely automake-generated, # this script deletes all Makefile.in files it can find. # # Requires: automake 1.9, autoconf 2.57+ # Conflicts: autoconf 2.13 set -e # Refresh GNU autotools toolchain. echo Cleaning autotools files... find -type d -name autom4te.cache -print0 | xargs -0 rm -rf \; find -type f \( -name missing -o -name install-sh -o -name mkinstalldirs \ -o -name depcomp -o -name ltmain.sh -o -name configure \ -o -name config.sub -o -name config.guess \ -o -name Makefile.in \) -print0 | xargs -0 rm -f echo Running autoreconf... autoreconf --force --install echo Running automake automake --add-missing echo Running intltoolize intltoolize # For the Debian package build test -d debian && { # link these in Debian builds rm -f config.sub config.guess ln -s /usr/share/misc/config.sub . ln -s /usr/share/misc/config.guess . # refresh list of executable scripts, to avoid possible breakage if # upstream tarball does not include the file or if it is mispackaged # for whatever reason. [ "$1" = "updateexec" ] && { echo Generating list of executable files... rm -f debian/executable.files find -type f -perm +111 ! -name '.*' -fprint debian/executable.files } # Remove any files in upstream tarball that we don't have in the Debian # package (because diff cannot remove files) version=`dpkg-parsechangelog | awk '/Version:/ { print $2 }' | sed -e 's/-[^-]\+$//'` source=`dpkg-parsechangelog | awk '/Source:/ { print $2 }' | tr -d ' '` if test -r ../${source}_${version}.orig.tar.gz ; then echo Generating list of files that should be removed... rm -f debian/deletable.files touch debian/deletable.files [ -e debian/tmp ] && rm -rf debian/tmp mkdir debian/tmp ( cd debian/tmp ; tar -zxf ../../../${source}_${version}.orig.tar.gz ) find debian/tmp/ -type f ! -name '.*' -print0 | xargs -0 -ri echo '{}' | \ while read -r i ; do if test -e "${i}" ; then filename=$(echo "${i}" | sed -e 's#.*debian/tmp/[^/]\+/##') test -e "${filename}" || echo "${filename}" >>debian/deletable.files fi done rm -fr debian/tmp else echo Emptying list of files that should be deleted... rm -f debian/deletable.files touch debian/deletable.files fi } exit 0 libunicap/intltool-update.in0000644000175000017500000000000013164711411016717 0ustar zmoelnigzmoelniglibunicap/common/0000755000175000017500000000000013164711411014545 5ustar zmoelnigzmoelniglibunicap/common/queue.c0000644000175000017500000001373313164711411016044 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004-2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "queue.h" #include #include /* void _dump_queue( struct _unicap_queue *queue ) */ /* { */ /* int i = -1; */ /* printf( "## dump queue\n" ); */ /* while( queue->next ) */ /* { */ /* printf( "entry: %d, addr: %p\n", i++, queue ); */ /* printf( "entry->next: %p\n", queue->next ); */ /* printf( "data: %p\n", queue->data ); */ /* printf( "sema: %p\n", queue->psema ); */ /* queue = queue->next; */ /* } */ /* printf( "entry: %d, addr: %p\n", i, queue ); */ /* printf( "entry->next: %p\n", queue->next ); */ /* printf( "data: %p\n", queue->data ); */ /* printf( "sema: %p\n\n", queue->psema ); */ /* } */ /** * ucutil_free_queue: * * Destroys a queue, freeing all contained elements and data. The head * pointer will not be freed. * * @queue: a queue * * Returns: Number of elements in the queue before it was destroyed */ int ucutil_free_queue( unicap_queue_t *queue ) { unicap_queue_t *entry; int ret; ret = ucutil_queue_get_size( queue ); if( sem_wait( queue->psema ) ){ TRACE( "FATAL: sem_wait failed\n" ); return -1; } while ( queue->next != NULL ){ entry = queue->next; if ( entry->data ){ free( entry->data ); } queue->next = entry->next; } sem_destroy(queue->psema); memset( queue, 0, sizeof( unicap_queue_t ) ); return ret; } /** * ucutil_destroy_queue: * * Destroys a queue, freeing all contained elements. The data and the * head pointer will not be freed. * * @queue: a queue * * Returns: Number of elements in the queue before it was destroyed */ int ucutil_destroy_queue( unicap_queue_t *queue ) { unicap_queue_t *entry; int ret; ret = ucutil_queue_get_size( queue ); if( sem_wait( queue->psema ) ){ TRACE( "FATAL: sem_wait failed\n" ); return -1; } while ( queue->next != NULL ){ entry = queue->next; queue->next = entry->next; } sem_destroy(queue->psema); memset( queue, 0, sizeof( unicap_queue_t ) ); return ret; } void ucutil_insert_back_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { struct _unicap_queue *tmp_queue; if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } tmp_queue = queue; // run to the end of the queue while( tmp_queue->next ) { tmp_queue = tmp_queue->next; } tmp_queue->next = entry; entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); return; } } void ucutil_insert_front_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } entry->next = queue->next; entry->psema = queue->psema; queue->next = entry; if( sem_post( queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } unicap_queue_t *ucutil_get_front_queue( unicap_queue_t *queue ) { struct _unicap_queue *entry; if( sem_wait( queue->psema ) ){ TRACE( "sem_wait failed!\n" ); return 0; } entry = queue->next; if( entry ){ // Remove entry from the list queue->next = entry->next; // Keep the semaphore entry->psema = queue->psema; entry->next = 0; } if( sem_post( queue->psema ) ){ TRACE( "FATAL: sem_post failed\n" ); } return entry; } void ucutil_move_to_queue( struct _unicap_queue *from_queue, struct _unicap_queue *to_queue ) { struct _unicap_queue *tmp_to_queue; struct _unicap_queue *tmp_from_queue; struct _unicap_queue *entry; if( sem_wait( from_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( sem_wait( to_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( !from_queue->next ) { entry = 0; goto out; } tmp_from_queue = from_queue; /////////////////////////////////////////////////////////////// entry = from_queue->next; if( tmp_from_queue->next ) { tmp_from_queue->next = tmp_from_queue->next->next; } entry->next = 0; ////////////////////////////////////////////////////////////// tmp_to_queue = to_queue; // run to the end of the queue while( tmp_to_queue->next ) { tmp_to_queue = tmp_to_queue->next; } tmp_to_queue->next = entry; entry->psema = to_queue->psema; out: if( sem_post( from_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } if( sem_post( to_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } /** * ucutil_queue_new: * * Allocates and initializes a queue. * * Returns: initialized queue */ unicap_queue_t *ucutil_queue_new( ) { unicap_queue_t *queue; queue = malloc( sizeof( unicap_queue_t ) ); ucutil_init_queue( queue ); return queue; } void ucutil_init_queue( unicap_queue_t *queue ) { memset( queue, 0, sizeof( unicap_queue_t ) ); if( sem_init( &queue->sema, 0, 1 ) ){ TRACE( "FATAL: sem_init failed\n" ); } queue->psema = &queue->sema; } int ucutil_queue_get_size( struct _unicap_queue *queue ) { int entries = 0; struct _unicap_queue *entry = queue; while( entry->next ) { entries++; entry = entry->next; } return entries; } libunicap/common/queue.h0000644000175000017500000000320313164711411016040 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __QUEUE_H__ #define __QUEUE_H__ #include "ucutil.h" #include #include struct _unicap_queue { sem_t sema; sem_t *psema; void * data; struct _unicap_queue *next; } unicap_queue; typedef struct _unicap_queue unicap_queue_t; __HIDDEN__ void ucutil_insert_back_queue( unicap_queue_t *queue, unicap_queue_t *entry ); __HIDDEN__ void ucutil_insert_front_queue( unicap_queue_t *queue, unicap_queue_t *entry ); __HIDDEN__ unicap_queue_t *ucutil_get_front_queue( unicap_queue_t *queue ); __HIDDEN__ void ucutil_move_to_queue( unicap_queue_t *from_queue, unicap_queue_t *to_queue ); __HIDDEN__ void ucutil_init_queue( unicap_queue_t * ); __HIDDEN__ unicap_queue_t *ucutil_queue_new( void ); __HIDDEN__ int ucutil_destroy_queue( unicap_queue_t *queue ); __HIDDEN__ int ucutil_queue_get_size( unicap_queue_t *queue ); #endif//__QUEUE_H__ libunicap/common/ucutil.h0000644000175000017500000000017513164711411016226 0ustar zmoelnigzmoelnig#ifndef __UCUTIL_H__ #define __UCUTIL_H__ #define __HIDDEN__ __attribute__((visibility("hidden"))) #endif//__UCUTIL_H__ libunicap/common/Makefile.am0000644000175000017500000000020213164711411016573 0ustar zmoelnigzmoelnigINCLUDES=-I../include noinst_LTLIBRARIES = libucutils.la libucutils_la_SOURCES = queue.c queue.h ucutil.h libucutils_la_LIBADD = libunicap/Makefile.am0000644000175000017500000000050713164711411015313 0ustar zmoelnigzmoelnigSUBDIRS=include common src doc po cpi data MAINTAINERCLEANFILES = Makefile.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libunicap.pc EXTRA_DIST = \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ install-sh \ libunicap.pc.in unversioneddistdir: distdir mv $(PACKAGE)-$(VERSION) unicap-dist libunicap/NEWS0000644000175000017500000000000013164711411013742 0ustar zmoelnigzmoelniglibunicap/ABOUT-NLS0000644000175000017500000023334013164711411014511 0ustar zmoelnigzmoelnig1 Notes on the Free Translation Project *************************************** Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that free software will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this `ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU `gettext' internally, itself available at your nearest GNU archive site. But you do _not_ need to install GNU `gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work on translations can contact the appropriate team. When reporting bugs in the `intl/' directory or bugs which may be related to internationalization, you should tell about the version of `gettext' which is used. The information can be found in the `intl/VERSION' file, in internationalized packages. 1.1 Quick configuration advice ============================== If you want to exploit the full power of internationalization, you should configure it using ./configure --with-included-gettext to force usage of internationalizing routines provided within this package, despite the existence of internationalizing capabilities in the operating system where this package is being installed. So far, only the `gettext' implementation in the GNU C library version 2 provides as many features (such as locale alias, message inheritance, automatic charset conversion or plural form handling) as the implementation here. It is also not possible to offer this additional functionality on top of a `catgets' implementation. Future versions of GNU `gettext' will very likely convey even more functionality. So it might be a good idea to change to GNU `gettext' as soon as possible. So you need _not_ provide this option if you are using GNU libc 2 or you have installed a recent copy of the GNU gettext package with the included `libintl'. 1.2 INSTALL Matters =================== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU `gettext'. Other packages have their own ways to internationalization, predating GNU `gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system already provides the GNU `gettext' functions. If not, the included GNU `gettext' library will be used. This library is wholly contained within this package, usually in the `intl/' subdirectory, so prior installation of the GNU `gettext' package is _not_ required. Installers may use special options at configuration time for changing the default behaviour. The commands: ./configure --with-included-gettext ./configure --disable-nls will, respectively, bypass any pre-existing `gettext' to use the internationalizing routines provided within this package, or else, _totally_ disable translation of messages. When you already have GNU `gettext' installed on your system and run configure without an option for your new package, `configure' will probably detect the previously built and installed `libintl.a' file and will decide to use this. This might not be desirable. You should use the more recent version of the GNU `gettext' library. I.e. if the file `intl/VERSION' shows that the library which comes with this package is more recent, you should use ./configure --with-included-gettext to prevent auto-detection. The configuration process will not test for the `catgets' function and therefore it will not be used. The reason is that even an emulation of `gettext' on top of `catgets' could not provide all the extensions of the GNU `gettext' library. Internationalized packages usually have many `po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at `configure' time by using the `--disable-nls' switch, all available translations are installed together with the package. However, the environment variable `LINGUAS' may be set, prior to configuration, to limit the installed set. `LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. 1.3 Using This Package ====================== As a user, if your language has been installed for this package, you only have to set the `LANG' environment variable to the appropriate `LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, and `CC' is an ISO 3166 two-letter country code. For example, let's suppose that you speak German and live in Germany. At the shell prompt, merely execute `setenv LANG de_DE' (in `csh'), `export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). This can be done from your `.login' or `.profile' file, once and for all. You might think that the country code specification is redundant. But in fact, some languages have dialects in different countries. For example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The country code serves to distinguish the dialects. The locale naming convention of `LL_CC', with `LL' denoting the language and `CC' denoting the country, is the one use on systems based on GNU libc. On other systems, some variations of this scheme are used, such as `LL' or `LL_CC.ENCODING'. You can get the list of locales supported by your system for your language by running the command `locale -a | grep '^LL''. Not all programs have translations for all languages. By default, an English message is shown in place of a nonexistent translation. If you understand other languages, you can set up a priority list of languages. This is done through a different environment variable, called `LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' for the purpose of message handling, but you still need to have `LANG' set to the primary language; this is required by other parts of the system libraries. For example, some Swedish users who would rather read translations in German than English for when Swedish is not available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. Special advice for Norwegian users: The language code for Norwegian bokma*l changed from `no' to `nb' recently (in 2003). During the transition period, while some message catalogs for this language are installed under `nb' and some older ones under `no', it's recommended for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and older translations are used. In the `LANGUAGE' environment variable, but not in the `LANG' environment variable, `LL_CC' combinations can be abbreviated as `LL' to denote the language's main dialect. For example, `de' is equivalent to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' (Portuguese as spoken in Portugal) in this context. 1.4 Translating Teams ===================== For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, `http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. The subscribing address is _not_ the same as the list itself, it has `-request' appended. For example, speakers of Swedish can send a message to `sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate _actively_ in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to `translation@iro.umontreal.ca' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skills are praised more than programming skills, here. 1.5 Available Packages ====================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of October 2006. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination, with a translation percentage of at least 50%. Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB eo +----------------------------------------------------+ GNUnet | [] | a2ps | [] [] [] [] [] | aegis | () | ant-phone | () | anubis | [] | ap-utils | | aspell | [] [] [] [] [] | bash | [] [] [] | batchelor | [] | bfd | | bibshelf | [] | binutils | [] | bison | [] [] | bison-runtime | | bluez-pin | [] [] [] [] [] | cflow | [] | clisp | [] [] | console-tools | [] [] | coreutils | [] [] [] | cpio | | cpplib | [] [] [] | cryptonit | [] | darkstat | [] () [] | dialog | [] [] [] [] [] [] | diffutils | [] [] [] [] [] [] | doodle | [] | e2fsprogs | [] [] | enscript | [] [] [] [] | error | [] [] [] [] | fetchmail | [] [] () [] | fileutils | [] [] | findutils | [] [] [] | flex | [] [] [] | fslint | [] | gas | | gawk | [] [] [] | gbiff | [] | gcal | [] | gcc | [] | gettext-examples | [] [] [] [] [] | gettext-runtime | [] [] [] [] [] | gettext-tools | [] [] | gimp-print | [] [] [] [] | gip | [] | gliv | [] | glunarclock | [] | gmult | [] [] | gnubiff | () | gnucash | () () [] | gnucash-glossary | [] () | gnuedu | | gnulib | [] [] [] [] [] [] | gnunet-gtk | | gnutls | | gpe-aerial | [] [] | gpe-beam | [] [] | gpe-calendar | | gpe-clock | [] [] | gpe-conf | [] [] | gpe-contacts | | gpe-edit | [] | gpe-filemanager | | gpe-go | [] | gpe-login | [] [] | gpe-ownerinfo | [] [] | gpe-package | | gpe-sketchbook | [] [] | gpe-su | [] [] | gpe-taskmanager | [] [] | gpe-timesheet | [] | gpe-today | [] [] | gpe-todo | | gphoto2 | [] [] [] [] | gprof | [] [] | gpsdrive | () () | gramadoir | [] [] | grep | [] [] [] [] [] [] | gretl | | gsasl | | gss | | gst-plugins | [] [] [] [] | gst-plugins-base | [] [] [] | gst-plugins-good | [] [] [] [] [] [] [] | gstreamer | [] [] [] [] [] [] [] | gtick | () | gtkam | [] [] [] | gtkorphan | [] [] | gtkspell | [] [] [] [] | gutenprint | [] | hello | [] [] [] [] [] | id-utils | [] [] | impost | | indent | [] [] [] | iso_3166 | [] [] | iso_3166_2 | | iso_4217 | [] | iso_639 | [] [] | jpilot | [] | jtag | | jwhois | | kbd | [] [] [] [] | keytouch | | keytouch-editor | | keytouch-keyboa... | | latrine | () | ld | [] | leafpad | [] [] [] [] [] | libc | [] [] [] [] [] | libexif | [] | libextractor | [] | libgpewidget | [] [] [] | libgpg-error | [] | libgphoto2 | [] [] | libgphoto2_port | [] [] | libgsasl | | libiconv | [] [] | libidn | [] [] | lifelines | [] () | lilypond | [] | lingoteach | | lynx | [] [] [] [] | m4 | [] [] [] [] | mailutils | [] | make | [] [] | man-db | [] () [] [] | minicom | [] [] [] | mysecretdiary | [] [] | nano | [] [] [] | nano_1_0 | [] () [] [] | opcodes | [] | parted | | pilot-qof | [] | psmisc | [] | pwdutils | | python | | qof | | radius | [] | recode | [] [] [] [] [] [] | rpm | [] [] | screem | | scrollkeeper | [] [] [] [] [] [] [] [] | sed | [] [] [] | sh-utils | [] [] | shared-mime-info | [] [] [] [] | sharutils | [] [] [] [] [] [] | shishi | | silky | | skencil | [] () | sketch | [] () | solfege | | soundtracker | [] [] | sp | [] | stardict | [] | system-tools-ba... | [] [] [] [] [] [] [] [] [] | tar | [] | texinfo | [] [] [] | textutils | [] [] [] | tin | () () | tp-robot | [] | tuxpaint | [] [] [] [] [] | unicode-han-tra... | | unicode-transla... | | util-linux | [] [] [] [] | vorbis-tools | [] [] [] [] | wastesedge | () | wdiff | [] [] [] [] | wget | [] [] | xchat | [] [] [] [] [] [] | xkeyboard-config | | xpad | [] [] | +----------------------------------------------------+ af am ar az be bg bs ca cs cy da de el en en_GB eo 10 0 1 2 9 22 1 42 41 2 60 95 16 1 17 16 es et eu fa fi fr ga gl gu he hi hr hu id is it +--------------------------------------------------+ GNUnet | | a2ps | [] [] [] () | aegis | | ant-phone | [] | anubis | [] | ap-utils | [] [] | aspell | [] [] [] | bash | [] [] [] | batchelor | [] [] | bfd | [] | bibshelf | [] [] [] | binutils | [] [] [] | bison | [] [] [] [] [] [] | bison-runtime | [] [] [] [] [] | bluez-pin | [] [] [] [] [] | cflow | [] | clisp | [] [] | console-tools | | coreutils | [] [] [] [] [] [] | cpio | [] [] [] | cpplib | [] [] | cryptonit | [] | darkstat | [] () [] [] [] | dialog | [] [] [] [] [] [] [] [] | diffutils | [] [] [] [] [] [] [] [] [] | doodle | [] [] | e2fsprogs | [] [] [] | enscript | [] [] [] | error | [] [] [] [] [] | fetchmail | [] | fileutils | [] [] [] [] [] [] | findutils | [] [] [] [] | flex | [] [] [] | fslint | [] | gas | [] [] | gawk | [] [] [] [] | gbiff | [] | gcal | [] [] | gcc | [] | gettext-examples | [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] | gettext-tools | [] [] [] | gimp-print | [] [] | gip | [] [] [] | gliv | () | glunarclock | [] [] [] | gmult | [] [] [] | gnubiff | () () | gnucash | () () () | gnucash-glossary | [] [] | gnuedu | [] | gnulib | [] [] [] [] [] [] [] [] | gnunet-gtk | | gnutls | | gpe-aerial | [] [] | gpe-beam | [] [] | gpe-calendar | | gpe-clock | [] [] [] [] | gpe-conf | [] | gpe-contacts | [] [] | gpe-edit | [] [] [] [] | gpe-filemanager | [] | gpe-go | [] [] [] | gpe-login | [] [] [] | gpe-ownerinfo | [] [] [] [] [] | gpe-package | [] | gpe-sketchbook | [] [] | gpe-su | [] [] [] [] | gpe-taskmanager | [] [] [] | gpe-timesheet | [] [] [] [] | gpe-today | [] [] [] [] | gpe-todo | [] | gphoto2 | [] [] [] [] [] | gprof | [] [] [] [] | gpsdrive | () () [] () | gramadoir | [] [] | grep | [] [] [] [] [] [] [] [] [] [] [] [] | gretl | [] [] [] | gsasl | [] [] | gss | [] | gst-plugins | [] [] [] | gst-plugins-base | [] [] | gst-plugins-good | [] [] [] | gstreamer | [] [] [] | gtick | [] | gtkam | [] [] [] [] | gtkorphan | [] [] | gtkspell | [] [] [] [] [] [] | gutenprint | [] | hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | id-utils | [] [] [] [] [] | impost | [] [] | indent | [] [] [] [] [] [] [] [] [] [] | iso_3166 | [] [] [] | iso_3166_2 | [] | iso_4217 | [] [] [] [] | iso_639 | [] [] [] [] [] | jpilot | [] [] | jtag | [] | jwhois | [] [] [] [] [] | kbd | [] [] | keytouch | [] | keytouch-editor | [] | keytouch-keyboa... | [] | latrine | [] [] [] | ld | [] [] | leafpad | [] [] [] [] [] [] | libc | [] [] [] [] [] | libexif | [] | libextractor | [] | libgpewidget | [] [] [] [] [] | libgpg-error | | libgphoto2 | [] [] [] | libgphoto2_port | [] [] | libgsasl | [] [] | libiconv | [] [] | libidn | [] [] | lifelines | () | lilypond | [] | lingoteach | [] [] [] | lynx | [] [] [] | m4 | [] [] [] [] | mailutils | [] [] | make | [] [] [] [] [] [] [] [] | man-db | () | minicom | [] [] [] [] | mysecretdiary | [] [] [] | nano | [] [] [] [] [] [] | nano_1_0 | [] [] [] [] [] | opcodes | [] [] [] [] | parted | [] [] [] [] | pilot-qof | | psmisc | [] [] [] | pwdutils | | python | | qof | [] | radius | [] [] | recode | [] [] [] [] [] [] [] [] | rpm | [] [] | screem | | scrollkeeper | [] [] [] | sed | [] [] [] [] [] | sh-utils | [] [] [] [] [] [] [] | shared-mime-info | [] [] [] [] [] [] | sharutils | [] [] [] [] [] [] [] [] | shishi | | silky | [] | skencil | [] [] | sketch | [] [] | solfege | [] | soundtracker | [] [] [] | sp | [] | stardict | [] | system-tools-ba... | [] [] [] [] [] [] [] [] | tar | [] [] [] [] [] [] [] | texinfo | [] [] | textutils | [] [] [] [] [] | tin | [] () | tp-robot | [] [] [] [] | tuxpaint | [] [] | unicode-han-tra... | | unicode-transla... | [] [] | util-linux | [] [] [] [] [] [] [] | vorbis-tools | [] [] | wastesedge | () | wdiff | [] [] [] [] [] [] [] [] | wget | [] [] [] [] [] [] [] [] | xchat | [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] | xpad | [] [] [] | +--------------------------------------------------+ es et eu fa fi fr ga gl gu he hi hr hu id is it 88 22 14 2 40 115 61 14 1 8 1 6 59 31 0 52 ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no +-------------------------------------------------+ GNUnet | | a2ps | () [] [] () | aegis | () | ant-phone | [] | anubis | [] [] [] | ap-utils | [] | aspell | [] [] | bash | [] | batchelor | [] [] | bfd | | bibshelf | [] | binutils | | bison | [] [] [] | bison-runtime | [] [] [] | bluez-pin | [] [] [] | cflow | | clisp | [] | console-tools | | coreutils | [] | cpio | | cpplib | [] | cryptonit | [] | darkstat | [] [] | dialog | [] [] | diffutils | [] [] [] | doodle | | e2fsprogs | [] | enscript | [] | error | [] | fetchmail | [] [] | fileutils | [] [] | findutils | [] | flex | [] [] | fslint | [] [] | gas | | gawk | [] [] | gbiff | [] | gcal | | gcc | | gettext-examples | [] [] | gettext-runtime | [] [] [] | gettext-tools | [] [] | gimp-print | [] [] | gip | [] [] | gliv | [] | glunarclock | [] [] | gmult | [] [] | gnubiff | | gnucash | () () | gnucash-glossary | [] | gnuedu | | gnulib | [] [] [] [] | gnunet-gtk | | gnutls | | gpe-aerial | [] | gpe-beam | [] | gpe-calendar | [] | gpe-clock | [] [] [] | gpe-conf | [] [] | gpe-contacts | [] | gpe-edit | [] [] [] | gpe-filemanager | [] [] | gpe-go | [] [] [] | gpe-login | [] [] [] | gpe-ownerinfo | [] [] | gpe-package | [] [] | gpe-sketchbook | [] [] | gpe-su | [] [] [] | gpe-taskmanager | [] [] [] [] | gpe-timesheet | [] | gpe-today | [] [] | gpe-todo | [] | gphoto2 | [] [] | gprof | | gpsdrive | () () () | gramadoir | () | grep | [] [] [] [] | gretl | | gsasl | [] | gss | | gst-plugins | [] | gst-plugins-base | | gst-plugins-good | [] | gstreamer | [] | gtick | | gtkam | [] | gtkorphan | [] | gtkspell | [] [] | gutenprint | | hello | [] [] [] [] [] [] | id-utils | [] | impost | | indent | [] [] | iso_3166 | [] | iso_3166_2 | [] | iso_4217 | [] [] [] | iso_639 | [] [] | jpilot | () () () | jtag | | jwhois | [] | kbd | [] | keytouch | [] | keytouch-editor | | keytouch-keyboa... | | latrine | [] | ld | | leafpad | [] [] | libc | [] [] [] [] [] | libexif | | libextractor | | libgpewidget | [] | libgpg-error | | libgphoto2 | [] | libgphoto2_port | [] | libgsasl | [] | libiconv | | libidn | [] [] | lifelines | [] | lilypond | | lingoteach | [] | lynx | [] [] | m4 | [] [] | mailutils | | make | [] [] [] | man-db | () | minicom | [] | mysecretdiary | [] | nano | [] [] [] | nano_1_0 | [] [] [] | opcodes | [] | parted | [] [] | pilot-qof | | psmisc | [] [] [] | pwdutils | | python | | qof | | radius | | recode | [] | rpm | [] [] | screem | [] | scrollkeeper | [] [] [] [] | sed | [] [] | sh-utils | [] [] | shared-mime-info | [] [] [] [] [] | sharutils | [] [] | shishi | | silky | [] | skencil | | sketch | | solfege | | soundtracker | | sp | () | stardict | [] [] | system-tools-ba... | [] [] [] [] | tar | [] [] [] | texinfo | [] [] [] | textutils | [] [] [] | tin | | tp-robot | [] | tuxpaint | [] | unicode-han-tra... | | unicode-transla... | | util-linux | [] [] | vorbis-tools | [] | wastesedge | [] | wdiff | [] [] | wget | [] [] | xchat | [] [] [] [] | xkeyboard-config | [] | xpad | [] [] [] | +-------------------------------------------------+ ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no 52 24 2 2 1 3 0 2 3 21 0 15 1 97 5 1 nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta +------------------------------------------------------+ GNUnet | | a2ps | () [] [] [] [] [] [] | aegis | () () | ant-phone | [] [] | anubis | [] [] [] | ap-utils | () | aspell | [] [] | bash | [] [] [] | batchelor | [] [] | bfd | | bibshelf | [] | binutils | [] [] | bison | [] [] [] [] [] | bison-runtime | [] [] [] [] | bluez-pin | [] [] [] [] [] [] [] [] [] | cflow | [] | clisp | [] | console-tools | [] | coreutils | [] [] [] [] | cpio | [] [] [] | cpplib | [] | cryptonit | [] [] | darkstat | [] [] [] [] [] [] | dialog | [] [] [] [] [] [] [] [] [] | diffutils | [] [] [] [] [] [] | doodle | [] [] | e2fsprogs | [] [] | enscript | [] [] [] [] [] | error | [] [] [] [] | fetchmail | [] [] [] | fileutils | [] [] [] [] [] | findutils | [] [] [] [] [] [] | flex | [] [] [] [] [] | fslint | [] [] [] [] | gas | | gawk | [] [] [] [] | gbiff | [] | gcal | [] | gcc | [] | gettext-examples | [] [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] [] [] | gettext-tools | [] [] [] [] [] [] [] | gimp-print | [] [] | gip | [] [] [] [] | gliv | [] [] [] [] | glunarclock | [] [] [] [] [] [] | gmult | [] [] [] [] | gnubiff | () | gnucash | () [] | gnucash-glossary | [] [] [] | gnuedu | | gnulib | [] [] [] [] [] | gnunet-gtk | [] | gnutls | [] [] | gpe-aerial | [] [] [] [] [] [] [] | gpe-beam | [] [] [] [] [] [] [] | gpe-calendar | [] | gpe-clock | [] [] [] [] [] [] [] [] | gpe-conf | [] [] [] [] [] [] [] | gpe-contacts | [] [] [] [] [] | gpe-edit | [] [] [] [] [] [] [] [] | gpe-filemanager | [] [] | gpe-go | [] [] [] [] [] [] | gpe-login | [] [] [] [] [] [] [] [] | gpe-ownerinfo | [] [] [] [] [] [] [] [] | gpe-package | [] [] | gpe-sketchbook | [] [] [] [] [] [] [] [] | gpe-su | [] [] [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] [] [] [] | gpe-timesheet | [] [] [] [] [] [] [] [] | gpe-today | [] [] [] [] [] [] [] [] | gpe-todo | [] [] [] [] | gphoto2 | [] [] [] [] [] | gprof | [] [] [] | gpsdrive | [] [] [] | gramadoir | [] [] | grep | [] [] [] [] [] [] [] [] | gretl | [] | gsasl | [] [] [] | gss | [] [] [] | gst-plugins | [] [] [] [] | gst-plugins-base | [] | gst-plugins-good | [] [] [] [] | gstreamer | [] [] [] | gtick | [] | gtkam | [] [] [] [] | gtkorphan | [] | gtkspell | [] [] [] [] [] [] [] [] | gutenprint | [] | hello | [] [] [] [] [] [] [] [] | id-utils | [] [] [] [] | impost | [] | indent | [] [] [] [] [] [] | iso_3166 | [] [] [] [] [] [] | iso_3166_2 | | iso_4217 | [] [] [] [] | iso_639 | [] [] [] [] | jpilot | | jtag | [] | jwhois | [] [] [] [] | kbd | [] [] [] | keytouch | [] | keytouch-editor | [] | keytouch-keyboa... | [] | latrine | [] [] | ld | [] | leafpad | [] [] [] [] [] [] | libc | [] [] [] [] [] | libexif | [] | libextractor | [] [] | libgpewidget | [] [] [] [] [] [] [] | libgpg-error | [] [] | libgphoto2 | [] | libgphoto2_port | [] [] [] | libgsasl | [] [] [] [] | libiconv | [] [] | libidn | [] [] () | lifelines | [] [] | lilypond | | lingoteach | [] | lynx | [] [] [] | m4 | [] [] [] [] [] | mailutils | [] [] [] [] | make | [] [] [] [] | man-db | [] [] | minicom | [] [] [] [] [] | mysecretdiary | [] [] [] [] | nano | [] [] [] | nano_1_0 | [] [] [] [] | opcodes | [] [] | parted | [] | pilot-qof | [] | psmisc | [] [] | pwdutils | [] [] | python | | qof | [] [] | radius | [] [] | recode | [] [] [] [] [] [] [] | rpm | [] [] [] [] | screem | | scrollkeeper | [] [] [] [] [] [] [] | sed | [] [] [] [] [] [] [] [] [] | sh-utils | [] [] [] | shared-mime-info | [] [] [] [] [] | sharutils | [] [] [] [] | shishi | [] | silky | [] | skencil | [] [] [] | sketch | [] [] [] | solfege | [] | soundtracker | [] [] | sp | | stardict | [] [] [] | system-tools-ba... | [] [] [] [] [] [] [] [] [] | tar | [] [] [] [] [] | texinfo | [] [] [] [] | textutils | [] [] [] | tin | () | tp-robot | [] | tuxpaint | [] [] [] [] [] | unicode-han-tra... | | unicode-transla... | | util-linux | [] [] [] [] | vorbis-tools | [] [] | wastesedge | | wdiff | [] [] [] [] [] [] | wget | [] [] [] [] | xchat | [] [] [] [] [] [] [] | xkeyboard-config | [] [] | xpad | [] [] [] | +------------------------------------------------------+ nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta 0 2 3 58 30 54 5 73 72 4 40 46 11 50 128 2 tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu +---------------------------------------------------+ GNUnet | [] | 2 a2ps | [] [] [] | 19 aegis | | 0 ant-phone | [] [] | 6 anubis | [] [] [] | 11 ap-utils | () [] | 4 aspell | [] [] [] | 15 bash | [] | 11 batchelor | [] [] | 9 bfd | | 1 bibshelf | [] | 7 binutils | [] [] [] | 9 bison | [] [] [] | 19 bison-runtime | [] [] [] | 15 bluez-pin | [] [] [] [] [] [] | 28 cflow | [] [] | 5 clisp | | 6 console-tools | [] [] | 5 coreutils | [] [] | 16 cpio | [] [] [] | 9 cpplib | [] [] [] [] | 11 cryptonit | | 5 darkstat | [] () () | 15 dialog | [] [] [] [] [] | 30 diffutils | [] [] [] [] | 28 doodle | [] | 6 e2fsprogs | [] [] | 10 enscript | [] [] [] | 16 error | [] [] [] [] | 18 fetchmail | [] [] | 12 fileutils | [] [] [] | 18 findutils | [] [] [] | 17 flex | [] [] | 15 fslint | [] | 9 gas | [] | 3 gawk | [] [] | 15 gbiff | [] | 5 gcal | [] | 5 gcc | [] [] [] | 6 gettext-examples | [] [] [] [] [] [] | 27 gettext-runtime | [] [] [] [] [] [] | 28 gettext-tools | [] [] [] [] [] | 19 gimp-print | [] [] | 12 gip | [] [] | 12 gliv | [] [] | 8 glunarclock | [] [] [] | 15 gmult | [] [] [] [] | 15 gnubiff | [] | 1 gnucash | () | 2 gnucash-glossary | [] [] | 9 gnuedu | [] | 2 gnulib | [] [] [] [] [] | 28 gnunet-gtk | | 1 gnutls | | 2 gpe-aerial | [] [] | 14 gpe-beam | [] [] | 14 gpe-calendar | [] | 3 gpe-clock | [] [] [] [] | 21 gpe-conf | [] [] | 14 gpe-contacts | [] [] | 10 gpe-edit | [] [] [] [] | 20 gpe-filemanager | [] | 6 gpe-go | [] [] | 15 gpe-login | [] [] [] [] [] | 21 gpe-ownerinfo | [] [] [] [] | 21 gpe-package | [] | 6 gpe-sketchbook | [] [] | 16 gpe-su | [] [] [] | 20 gpe-taskmanager | [] [] [] | 20 gpe-timesheet | [] [] [] [] | 18 gpe-today | [] [] [] [] [] | 21 gpe-todo | [] | 7 gphoto2 | [] [] [] [] | 20 gprof | [] [] | 11 gpsdrive | | 4 gramadoir | [] | 7 grep | [] [] [] [] | 34 gretl | | 4 gsasl | [] [] | 8 gss | [] | 5 gst-plugins | [] [] [] | 15 gst-plugins-base | [] [] [] | 9 gst-plugins-good | [] [] [] [] [] | 20 gstreamer | [] [] [] | 17 gtick | [] | 3 gtkam | [] | 13 gtkorphan | [] | 7 gtkspell | [] [] [] [] [] [] | 26 gutenprint | | 3 hello | [] [] [] [] [] | 37 id-utils | [] [] | 14 impost | [] | 4 indent | [] [] [] [] | 25 iso_3166 | [] [] [] [] | 16 iso_3166_2 | | 2 iso_4217 | [] [] | 14 iso_639 | [] | 14 jpilot | [] [] [] [] | 7 jtag | [] | 3 jwhois | [] [] [] | 13 kbd | [] [] | 12 keytouch | [] | 4 keytouch-editor | | 2 keytouch-keyboa... | [] | 3 latrine | [] [] | 8 ld | [] [] [] [] | 8 leafpad | [] [] [] [] | 23 libc | [] [] [] | 23 libexif | [] | 4 libextractor | [] | 5 libgpewidget | [] [] [] | 19 libgpg-error | [] | 4 libgphoto2 | [] | 8 libgphoto2_port | [] [] [] | 11 libgsasl | [] | 8 libiconv | [] | 7 libidn | [] [] | 10 lifelines | | 4 lilypond | | 2 lingoteach | [] | 6 lynx | [] [] [] | 15 m4 | [] [] [] | 18 mailutils | [] | 8 make | [] [] [] | 20 man-db | [] | 6 minicom | [] | 14 mysecretdiary | [] [] | 12 nano | [] [] | 17 nano_1_0 | [] [] [] | 18 opcodes | [] [] | 10 parted | [] [] [] | 10 pilot-qof | [] | 3 psmisc | [] | 10 pwdutils | [] | 3 python | | 0 qof | [] | 4 radius | [] | 6 recode | [] [] [] | 25 rpm | [] [] [] [] | 14 screem | [] | 2 scrollkeeper | [] [] [] [] | 26 sed | [] [] [] | 22 sh-utils | [] | 15 shared-mime-info | [] [] [] [] | 24 sharutils | [] [] [] | 23 shishi | | 1 silky | [] | 4 skencil | [] | 7 sketch | | 6 solfege | | 2 soundtracker | [] [] | 9 sp | [] | 3 stardict | [] [] [] [] | 11 system-tools-ba... | [] [] [] [] [] [] [] | 37 tar | [] [] [] [] | 20 texinfo | [] [] [] | 15 textutils | [] [] [] | 17 tin | | 1 tp-robot | [] [] [] | 10 tuxpaint | [] [] [] | 16 unicode-han-tra... | | 0 unicode-transla... | | 2 util-linux | [] [] [] | 20 vorbis-tools | [] [] | 11 wastesedge | | 1 wdiff | [] [] | 22 wget | [] [] [] | 19 xchat | [] [] [] [] | 29 xkeyboard-config | [] [] [] [] | 11 xpad | [] [] [] | 14 +---------------------------------------------------+ 77 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu 170 domains 0 1 1 77 39 0 136 10 1 48 5 54 0 2028 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If October 2006 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at `http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. 1.6 Using `gettext' in new packages =================================== If you are writing a freely available program and want to internationalize it you are welcome to use GNU `gettext' in your package. Of course you have to respect the GNU Library General Public License which covers the use of the GNU `gettext' library. This means in particular that even non-free programs can use `libintl' as a shared library, whereas only free software can use `libintl' as a static library or use modified versions of `libintl'. Once the sources are changed appropriately and the setup can handle the use of `gettext' the only thing missing are the translations. The Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact `translation@iro.umontreal.ca' to make the `.pot' files available to the translation teams. libunicap/doc/0000755000175000017500000000000013164711411014022 5ustar zmoelnigzmoelniglibunicap/doc/Makefile.am0000644000175000017500000000002213164711411016050 0ustar zmoelnigzmoelnigSUBDIRS=libunicap libunicap/doc/libunicap/0000755000175000017500000000000013164711411015770 5ustar zmoelnigzmoelniglibunicap/doc/libunicap/Makefile.am0000644000175000017500000000540313164711411020026 0ustar zmoelnigzmoelnig## Process this file with automake to produce Makefile.in # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # This is a blank Makefile.am for using gtk-doc. # Copy this to your project's API docs directory and modify the variables to # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples # of using the various options. # The name of the module, e.g. 'glib'. DOC_MODULE=libunicap # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. # e.g. DOC_SOURCE_DIR=../../../gtk DOC_SOURCE_DIR=../../src --source-dir=../../include # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS= # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS=--sgml-mode --output-format=xml # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl MKTMPL_OPTIONS= # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB=$(top_srcdir)/include/*.h CFILE_GLOB=$(top_srcdir)/src/*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES= # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml expand_content_files= # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) INCLUDES=`pkg-config --cflags glib-2.0` -I$(top_srcdir) -I$(top_builddir) GTKDOC_LIBS=`pkg-config --libs glib-2.0` -L$(top_builddir)/libunicap/.libs/ -lunicap # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += libunicap/doc/libunicap/tmpl/0000755000175000017500000000000013164711411016744 5ustar zmoelnigzmoelniglibunicap/doc/libunicap/tmpl/unicap.sgml0000644000175000017500000001444113164711411021113 0ustar zmoelnigzmoelnig unicap @UNICAP_BUFFER_TYPE_USER: @UNICAP_BUFFER_TYPE_SYSTEM: @identifier: @model_name: @vendor_name: @vendor_id: @cpi_layer: @device: @flags: @x: @y: @width: @height: @identifier: @size: @min_size: @max_size: @h_stepping: @v_stepping: @sizes: @size_count: @bpp: @fourcc: @flags: @buffer_types: @system_buffer_count: @buffer_size: @buffer_type: @format: @frame_number: @fill_time: @duration: @capture_start_time: @data: @buffer_size: @type: @flags: @priv: @UNICAP_FLAGS_MANUAL: @UNICAP_FLAGS_AUTO: @UNICAP_FLAGS_ONE_PUSH: @UNICAP_FLAGS_READ_OUT: @UNICAP_FLAGS_ON_OFF: @UNICAP_FLAGS_READ_ONLY: @UNICAP_FLAGS_FORMAT_CHANGE: @UNICAP_FLAGS_WRITE_ONLY: @UNICAP_FLAGS_CHECK_STEPPING: @UNICAP_FLAGS_DUMMY_VALUE: @min: @max: @values: @value_count: @menu_items: @menu_item_count: @UNICAP_PROPERTY_TYPE_RANGE: @UNICAP_PROPERTY_TYPE_VALUE_LIST: @UNICAP_PROPERTY_TYPE_MENU: @UNICAP_PROPERTY_TYPE_DATA: @UNICAP_PROPERTY_TYPE_FLAGS: @UNICAP_PROPERTY_TYPE_UNKNOWN: @identifier: @category: @unit: @relations: @relations_count: @menu_item: @value_list: @menu: @stepping: @type: @flags: @flags_mask: @property_data: @property_data_size: @UNICAP_EVENT_FIRST: @UNICAP_EVENT_DEVICE_REMOVED: @UNICAP_EVENT_NEW_DEVICE: @UNICAP_EVENT_NEW_FRAME: @UNICAP_EVENT_DROP_FRAME: @UNICAP_EVENT_LAST: @event: @Varargs: @event: @handle: @buffer: @user_ptr: @event: @handle: @user_ptr: @event: @device: @user_ptr: @major: @minor: @micro: @Returns: @count: @Returns: @specifier: @device: @index: @Returns: @handle: @device: @Returns: @handle: @event: @callback: @user_ptr: @Returns: @handle: @Returns: @handle: @device: @Returns: @handle: @Returns: @handle: @count: @Returns: @handle: @specifier: @format: @index: @Returns: @handle: @format: @Returns: @handle: @format: @Returns: @handle: @count: @Returns: @handle: @specifier: @property: @index: @Returns: @handle: @property: @Returns: @handle: @identifier: @value: @Returns: @handle: @identifier: @Returns: @handle: @identifier: @Returns: @handle: @identifier: @Returns: @handle: @property: @Returns: @handle: @identifier: @value: @Returns: @handle: @identifier: @value: @Returns: @handle: @identifier: @enabled: @Returns: @handle: @Returns: @handle: @Returns: @handle: @data_buffer: @Returns: @handle: @data_buffer: @Returns: @handle: @data_buffer: @Returns: @handle: @count: @Returns: libunicap/doc/libunicap/tmpl/libunicap-unused.sgml0000644000175000017500000000017113164711411023076 0ustar zmoelnigzmoelnig libunicap/doc/libunicap/tmpl/unicap_private.sgml0000644000175000017500000000144513164711411022645 0ustar zmoelnigzmoelnig unicap_private @func: @user_ptr: @shm_reg_version: @device_identifier: @use_count: @stream_owner: @properties_owner: @device: @cpi: @dlhandle: @cpi_data: @cpi_flags: @sem_key: @sem_id: @ref_count: @lock: @cb_info: @count: @Returns: libunicap/doc/libunicap/tmpl/unicap_helpers.sgml0000644000175000017500000000045613164711411022636 0ustar zmoelnigzmoelnig unicap_helpers libunicap/doc/libunicap/tmpl/check_match.sgml0000644000175000017500000000045313164711411022063 0ustar zmoelnigzmoelnig check_match libunicap/doc/libunicap/libunicap-docs.sgml0000644000175000017500000000060613164711411021552 0ustar zmoelnigzmoelnig Unicap Reference Manual unicap libunicap/doc/libunicap/libunicap-sections.txt0000644000175000017500000000262113164711411022325 0ustar zmoelnigzmoelnig
check_match
unicap_private unicap_callback_info unicap_shm_reg unicap_handle unicap_real_enumerate_devices
unicap unicap_buffer_type_t unicap_device_t unicap_rect_t unicap_format_t unicap_data_buffer_t unicap_property_flags_t unicap_property_range_t unicap_property_value_list_t unicap_property_menu_t unicap_property_type_enum_t unicap_property_t unicap_event_t UNICAP_FLAGS_MANUAL UNICAP_FLAGS_AUTO UNICAP_FLAGS_ONE_PUSH UNICAP_FLAGS_READ_OUT UNICAP_FLAGS_ON_OFF UNICAP_FLAGS_READ_ONLY UNICAP_FLAGS_FORMAT_CHANGE unicap_callback_t unicap_new_frame_callback_t unicap_drop_frame_callback_t unicap_new_device_callback_t unicap_check_version unicap_reenumerate_devices unicap_enumerate_devices unicap_open unicap_register_callback unicap_close unicap_get_device unicap_clone_handle unicap_reenumerate_formats unicap_enumerate_formats unicap_set_format unicap_get_format unicap_reenumerate_properties unicap_enumerate_properties unicap_set_property unicap_set_property_value unicap_set_property_manual unicap_set_property_auto unicap_set_property_one_push unicap_get_property unicap_get_property_value unicap_get_property_menu unicap_get_property_auto unicap_start_capture unicap_stop_capture unicap_queue_buffer unicap_dequeue_buffer unicap_wait_buffer unicap_poll_buffer
unicap_helpers
libunicap/doc/libunicap/libunicap-overrides.txt0000644000175000017500000000122013164711411022472 0ustar zmoelnigzmoelnig unicap_property_t struct unicap_property_t { char identifier[128]; char category[128]; char unit[128]; char **relations; int relations_count; union double value; char menu_item[128]; union unicap_property_range_t range; unicap_property_value_list_t value_list; unicap_property_menu_t menu; double stepping; unicap_property_type_enum_t type; unicap_property_flags_t flags; unicap_property_flags_t flags_mask; void *property_data; size_t property_data_size; }; libunicap/doc/libunicap/libunicap.types0000644000175000017500000000000113164711411021013 0ustar zmoelnigzmoelnig libunicap/ChangeLog0000644000175000017500000015517513164711411015045 0ustar zmoelnigzmoelnig2010-09-19 Arne Caspari * src/unicap.c (unicap_open): fix: returned uninitialized status (unicap_data_buffer_new): fix: buffer_structure was initialized before allocated * configure.ac: euvccam is now enabled by default 2010-01-25 Arne Caspari * include/unicap.h (enum): add flags for interlaced buffers * cpi/vid21394/vid21394_base.c (_vid21394_new_iso_handler): Mark buffers as interlaced and odd field first 2010-01-19 Arne Caspari * configure.ac: Added euvccam plugin 2009-10-08 Arne Caspari * libunicap/unicap.c (unicap_dequeue_buffer): fix: allow to dequeue buffer if no stream lock was acquired at all 2009-10-01 Arne Caspari * common/queue.c: code cleanup: join duplicate queue.c files into a convenience library 2009-09-28 Arne Caspari * libucil/video_file.h: using vtables for encoding modules ( patch from Martin Tschoepe ) * libucil/queue.c (_get_front_queue): code cleanup ( patch from Martin Tschoepe ) 2009-09-16 Arne Caspari * libunicapgtk/libunicapgtk.pc.in (Libs): removed external libs - they should not be neccessary here * libucil/libucil.pc.in (Cflags): removed external libs - they should not be neccessary here 2009-08-05 Arne Caspari * libunicapgtk/unicapgtk_device_property.c (range_value_changed_cb): only allow values that are multiples of property.stepping 2009-07-27 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (struct _UnicapgtkVideoDisplay): fix cropping * libunicapgtk/backend_gtk.c (backend_gtk_set_crop): fix cropping * libunicap/unicap.c (lookup_device_cache): reuse existing handles during unicap_open * cpi/v4l2cpi/v4l2.c (v4l2_set_format): stop and restart video stream when format changes 2009-07-24 Arne Caspari * libunicapgtk/unicapgtk_device_property.c (unicapgtk_device_property_redraw): fix: when updating a property, also update the range 2009-06-23 Arne Caspari * cpi/v4l2cpi/tisuvccam.c (tisuvccam_get_wb_auto): fix: read back white balance auto mode correctly 2009-06-17 Arne Caspari * include/unicap.h: typo 2009-06-08 Arne Caspari * libucil/draw.c (clip_line): fix deadlock when line is completely outside region 2009-02-19 Arne Caspari * libucil/ucil_rawavi.c (struct _ucil_rawavi_video_file_object): allow arbitrary FourCCs ( patch from Martin Tschoepe ) * libucil/ucil_theora.c (encode_parse_parameters): set frame_interval correctly for frame rates != 30 FPS ( Patch from Martin Tschoepe ) 2008-12-01 Arne Caspari * cpi/v4l2cpi/v4l2.c (v4l2_reenumerate_formats): stupid typo * libucil/ucil_rawavi.c (ucil_rawavi_close_video_file): more error handling 2008-11-25 Arne Caspari * include/unicap.h: src parameter of unicap_copy_format is const 2008-09-29 Arne Caspari * cpi/v4l2cpi/v4l2.c: use libv4l2 mmap and mmunmap functions ( patch from Hans de Goede ) do not use ENUM_FRAMESIZES when camera does not support it ( patch from Hans de Goede ) also try 176x144 frame size ( patch from Hans de Goede ) * libunicap/unicap.c : Install plugins in correct directory for x64 systems ( patch from Hans de Goede ) * libucil/ucil_theora.c (downsize_yuv420p): fix: allow arbitrary scaling factors 2008-09-24 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (load_device_defaults): reset controls when update button got clicked ( Patch from Martin Tschoepe ) 2008-09-16 Arne Caspari * cpi/v4l2cpi/v4l2.c: implemented libv4l2 support * cpi/v4l2cpi/Makefile.am: renamed v4l2 to v4l2cpi to avoid clash with libv4l2 2008-09-14 Arne Caspari * libucil/ucil_theora.c (ucil_theora_close_video_file): add a timeout to avoid hangs after a long recording ( reported in the forums ) * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_get_still_image): add destroy func to free allocated memory 2008-09-10 Arne Caspari * include/unicap.h (enum): introduced flags to signal significant bits in video data ( patch from Sven Neumann ) 2008-09-09 Arne Caspari * libunicapgtk/backend_gtk.c (backend_gtk_destroy): add backend locks to destroy func ( patch from Sven Neumann ) * libunicapgtk/backend_xv.c (backend_xv_destroy): add backend locks to destroy func ( patch from Sven Neumann ) * libucil/colorspace.c (ucil_convert_buffer): better debug output ( patch from Sven Neumann ) 2008-09-08 Arne Caspari * libunicapgtk/unicapgtk_video_format_selection.c (format_id_changed_cb): always add max format size to the list of default formats for size ranges ( patch from Sven Neumann ) 2008-09-04 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (uri_escape_string): replace g_uri_escape_string with uri_escape_string implementation from Sven Neumann 2008-08-29 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (unicapgtk_property_dialog_class_init): update-interval should not be a construct-only property * libunicapgtk/unicapgtk_video_format_selection.c (format_id_changed_cb): create a size box for devices which only provide a size range 2008-08-28 Arne Caspari * libunicap/check_match.c (_check_format_match): do not check cropping size for height ( as for width ) 2008-08-19 Arne Caspari * libucil/ucil_theora.c: constness and better error reporting ( Patch from Sven Neumann ) * libucil/ucil.h: added const to ucil_create_video_file ( Patch from Sven Neumann ) 2008-08-15 Arne Caspari * libunicapgtk/unicapgtk_device_property.c (unicapgtk_pack_device_property): fix PROPERTY_TYPE_FLAGS handling ( patch by Sven Neumann ) * cpi/v4l2/tiseuvccam.c (tiseuvccam_override_property): fix compile issue with kernel versions providing their own uvc_compat definitions * cpi/dcam/dcam_property.c (dcam_init_trigger_property): Check range of trigger property 2008-08-06 Arne Caspari * libucil/colorspace.c (yuv420ptoyuyv): fixed wrong conversion * libucil/ucil_rawavi.c: fix endianess issue (ucil_rawavi_encode_frame): fix: buffer locking issue * libunicapgtk/unicapgtk_property_dialog.c (load_device_defaults): fixed: escape special chars from path names, fixes Defaults button not working * libucil/colorspace.c (yuv420ptorgb24): fixed wrong conversion 2008-07-30 Arne Caspari * cpi/v4l2/v4l2.c: remove iSight adaptor for it is incompatible with newer firmwares 2008-07-16 Arne Caspari * libucil/ucil_theora.c: implemented downsize option 2008-07-10 Arne Caspari * include/unicap.h: unregister_callback 2008-07-01 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_enum_frameintervals): check for double frame intervals and drop them 2008-06-30 Arne Caspari * libunicapgtk/unicapgtk_device_property.c (menu_changed_cb): fix: i18n issue 2008-06-27 Arne Caspari * libunicapgtk/unicapgtk_device_property.h: make type check macros more like Gtk ones * libunicapgtk/unicapgtk_property_dialog.h: make type check macros more like Gtk ones * libunicapgtk/unicapgtk_video_display.h (UNICAPGTK_TYPE_VIDEO_DISPLAY): make type check macros more like Gtk ones 2008-06-26 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_capture_start): fix: capture_start sometimes failed because id found no free buffers (v4l2_set_frame_interval): fix frame interval property 2008-06-24 Arne Caspari * cpi/dcam/dcam_property.c (dcam_init_property_std_flags): added trigger polarity (dcam_init_trigger_property): trigger polarity 2008-06-19 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_still_image): emit signal when a still image gets set 2008-06-11 Arne Caspari * libucil/Makefile.am (AM_CFLAGS): compile with -fno-strict-aliasing * cpi/vid21394/visca.c: fixed some bugs that might cause VISCA commands to fail * cpi/vid21394/vid21394_base.c: code cleanup * cpi/v4l2/tisuvccam.c (TISUVCPropertyOverrides): made all identifiers lowercase code cleanup * cpi/v4l/v4l.c: code cleanup * cpi/dcam/Makefile.am (libdcam_la_CFLAGS): compile with -fno-strict-aliasing, workaround for compiler warnings * cpi/dcam/dcam_property.c: slight code cleanup * cpi/dcam/dcam.c: added missing include to fix compiler warning * cpi/v4l2/v4l2.c (queue_system_buffers): initialize v4l2 structs with 0, fixes compatibility issues with bttv driver * cpi/v4l2/tiseuvccam.c: support for TIS CMOS cameras 2008-06-02 Arne Caspari * cpi/vid21394/vid21394_cpi.c (cpi_capture_start): only set running flag on success 2008-05-28 Arne Caspari * libucil/colorspace.c (rgb242yuyv): new color conversion, fixes not working still image preview for YUY2 ( USB Camera ) formats 2008-05-22 Arne Caspari * libucil/ucil_audio.c (ucil_audio_list_cards): added audio abstraction 2008-05-20 Arne Caspari * libucil/ucil_rawavi.c (ucil_rawavi_close_video_file): fix wrong chunk size (ucil_rawavi_create_video_file): default to 30000 ms per frame 2008-05-19 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_still_image): allow still images to be set in pause mode * libunicapgtk/backend_gtk.c (scale_image): change interpolation type * libucil/video_file.c (get_codec_id): added support for avi/raw * libucil/colorspace.c (conversions): new alias: grey->y800 2008-05-18 Arne Caspari * libunicapgtk/Makefile.am : patch from Yi Zhan : fix build issue with IA64 * libucil/ucil_theora.c (ucil_theora_create_video_file): disable async_audio_encoding when audio is disabled 2008-05-13 Arne Caspari * libucil/ucil_theora.c (ucil_theora_encode_frame): fix possible deadlock of buffers 2008-05-12 Arne Caspari * libucil/colorspace.c (rgb242uyvy): fixed conversion 2008-05-07 Arne Caspari * libucil/draw.c (ucil_draw_box): added YUYV colorspace 2008-05-06 Arne Caspari * cpi/v4l2/v4l2.c (count_properties_ext): added compatibility fix for older kernel versions 2008-04-23 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_reenumerate_properties): change property enumeration to work with new uvcvideo driver versions 2008-04-20 Arne Caspari * libucil/colorspace.c: fixed rgb->i420 conversions 2008-04-18 Arne Caspari * libucil/colorspace.c (conversions): added bgr24toy420p (conversions): fixed some GUIDs 2008-03-31 Arne Caspari * include/unicap.h: added convenience functions for property access 2008-03-18 Arne Caspari * cpi/v4l2/v4l2.c (fourcc_bpp_map): added format BA81 * libucil/colorspace.c (conversions): added mapping for BA81 2008-02-14 Arne Caspari * libunicapgtk/backend_xv.h: declare functions with visibility hidden * libunicapgtk/cs_xfm.c: removed ( now using ucil ) * libunicapgtk/cs_xfm.h: removed ( now using ucil ) 2008-02-09 Arne Caspari * cpi/vid21394/vid21394_base.c: removed printfs 2008-02-04 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (unicapgtk_property_dialog_reset): don't select last page when no page was previously selected 2008-02-02 Arne Caspari * libucil/draw.c (ucil_draw_line): added clipping 2008-01-23 Arne Caspari * cpi/v4l2/v4l2.c (try_enum_framesizes): use VIDIOC_ENUM_FRAMESIZES when available 2008-01-10 Arne Caspari * cpi/v4l2/tisuvccam.c (tisuvc_fmt_v4l2_to_uc_func): map TIS custom formats from v4l2 to unicap 2008-01-09 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_uc_compat_list): added support for custom controls * cpi/v4l2/tisuvccam.c: handler for custom controls of TIS UVC cameras 2007-12-10 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_reenumerate_properties): revert 2007-12-07 Arne Caspari * Makefile.am (EXTRA_DIST): added OpenCV example 2007-12-05 Arne Caspari * libunicapgtk/unicapgtk_device_selection.h: fix compile error with C++ compiler 2007-11-30 Arne Caspari * examples/c/gl/gl-video.c (load_shader): added OpenGL example 2007-11-27 Arne Caspari * libucil/ucil.h: renamed reserved variable name delete ( thanks Benjamin Knopp ) 2007-11-26 Arne Caspari * cpi/vid21394/vid21394_base.c (vid21394_wait_buffer): applied patch from Dr. Douglas C. MacKenzie: fix 1/2 second delay in unicap_wait_buffer * libucil/ucil_theora.c (ucil_theora_close_video_file): fix compile/link errors when compiling ucil_theora without alsa support ( patch: Sven Neumann ) * configure.in: missing pangoft2 package 2007-10-23 Arne Caspari * libucil/yuvops.c (ucil_composite_UYVY_YUVA): UYVY composite function (ucil_composite_YUYV_YUVA): added YUY2 composite function * libunicapgtk/unicapgtk_property_dialog.c (unicapgtk_property_dialog_init): added update button 2007-10-17 Arne Caspari * libucil/yuvops.c (ucil_composite_UYVY_YUVA): added 2007-10-04 Arne Caspari * cpi/dcam/dcam_property.c (dcam_set_gpio_property): fixed bug: property->data overwrite 2007-09-27 Arne Caspari * libunicapgtk/unicapgtk_video_display.c: allow application to force a fourcc * libunicapgtk/unicapgtk_property_dialog.c: different size groups for labels on each page * libunicapgtk/unicapgtk_device_property.c: i18n support * libucil/ucil_alsa.c: new alsa support * libucil/ucil_theora.c: audio (vorbis) support * libucil/draw.c (ucil_set_pixel): support I420 * libucil/colorspace.c (conversions): new fourcc: YUY2 (ucil_convert_buffer): set bpp on target buffer * include/unicap.h: added buffer lock flags * cpi/vid21394/vid21394_cpi.c (cpi_capture_stop): fix segfault when stopping stream without a prefious capture_start * cpi/v4l2/v4l2.c: i18n support open NONBLOCK during enumeration use predefined list of supported video format sizes for known devices * cpi/v4l/v4l.c (v4l_enumerate_devices): open NONBLOCK * cpi/dcam/dcam_property_table.h: i18n support 2007-09-11 Arne Caspari * libucil/ucil_theora.c (encode_parse_args): added blocking mode 2007-09-06 Arne Caspari * libunicapgtk/unicapgtk_device_property.c: i18n support * libunicapgtk/unicapgtk.c: i18n support * libucil/ucil_theora.c: initial audio support * libucil/ucil_alsa.h: initial audio support ( still broken ) * libucil/ucil_alsa.c: initial audio support ( still broken ) * cpi/v4l2/v4l2_i18n_strings.h: i18n support * cpi/v4l2/v4l2.c (webcam_sizes): use stored tables of supported sizes for known devices to increase startup speed (v4l2_enumerate_devices): open O_NONBLOCK to avoid issues with Luca's drivers * cpi/v4l/v4l.c (v4l_enumerate_devices): open O_NONBLOCK to avoid problems with Lucas drivers * cpi/dcam/dcam_property_table.h: i18n support 2007-09-04 Arne Caspari * libunicapgtk/backend_xv.c (backend_xv_destroy): fix: unlock port 2007-08-30 gettextize * m4/gettext.m4: New file, from gettext-0.16.1. * m4/iconv.m4: New file, from gettext-0.16.1. * m4/lib-ld.m4: New file, from gettext-0.16.1. * m4/lib-link.m4: New file, from gettext-0.16.1. * m4/lib-prefix.m4: New file, from gettext-0.16.1. * m4/nls.m4: New file, from gettext-0.16.1. * m4/po.m4: New file, from gettext-0.16.1. * m4/progtest.m4: New file, from gettext-0.16.1. * Makefile.am (SUBDIRS): Add po. (ACLOCAL_AMFLAGS): New variable. (EXTRA_DIST): Add config.rpath. * configure.in (AC_CONFIG_FILES): Add po/Makefile.in. 2007-08-28 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_open): fix small memleak * libunicapgtk/backend_xv.c (backend_xv_init): fix small memleak 2007-08-21 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (set_backend): include backends - removed modules 2007-08-15 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_scale_to_fit): fixed bugs: output size not updated correctly; size allocation not updated correctly * libunicapgtk/display_backends/backend_xv.c (backend_set_scale_to_fit): fix 2007-08-01 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c: derive wron GTK_DIALOG instead of GTK_WINDOW ( patch: Sven Neumann ) * libunicapgtk/display_backends/backend_xv.c (backend_init): set dropout color not to be pure blue * libunicap/unicap.c (enumerate_devices): versioned cpi directory 2007-07-31 Arne Caspari * libucil/colorspace.c (y4202rgb24): new conversion (y4202rgb32): new conversion 2007-07-12 Arne Caspari * libunicapgtk/display_backends/cs_xfm.c: correctly use UCIL 2007-07-10 Arne Caspari * libunicapgtk/unicapgtk.c (unicapgtk_load_device_state): if device identifier does not match, also try vendor_name and model_name * cpi/dcam/dcam_capture.c (_dcam_dma_setup): make capture buffer memory writable 2007-07-09 Arne Caspari * libunicapgtk/display_backends/backend_xv.c (backend_destroy): fix: Xv port leak * libucil/colorspace.c (yuv420ptoyuyv): fixed conversions to/from yuv420p 2007-07-06 Arne Caspari * libunicapgtk/display_backends/backend_gtk.c (backend_get_image_data): fix: backend locking * libucil/colorspace.c (ucil_conversion_supported): fix: patch from Benjamin Knopp * doc/reference/libunicapgtk/Makefile.am (GTKDOC_LIBS): patch from Sven Neumann * doc/reference/libunicapgtk/libunicapgtk.types: patch from Sven Neumann 2007-07-05 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_handle): fix: do not change video format when setting a handle 2007-07-02 Arne Caspari * libucil/colorspace.c (yuv420ptouyvy): fix 2007-06-27 Arne Caspari * libucil/colorspace.c (conversions): fix: yuyv <> i420p 2007-06-26 Arne Caspari * libucil/colorspace.c (ucil_conversion_supported): fix: patch from Benjamin Knopp 2007-06-18 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (timeout_cb): fix: disp_time overrun * cpi/v4l2/v4l2.c (v4l2_reenumerate_formats): add fourcc to format identifier 2007-06-15 Arne Caspari * cpi/vid21394/vid21394_cpi.c (cpi_register): allow static linkage * cpi/dcam/dcam.c (cpi_register): allow static linkage * cpi/v4l2/v4l2.c (cpi_register): allow static linkage * cpi/v4l/v4l.c (cpi_register): allow static linkage * configure.in: new option: --enable-static-cpi * libunicap/unicap.c: allow static linkage of cpis 2007-05-19 Arne Caspari * libunicapgtk/unicapgtk.c (unicapgtk_save_device_state): fix: added missing unicap_get_property * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_pause): fix: used wrong buffer for pause 2007-05-11 Arne Caspari * libunicap/unicap.c (unicap_open): remove clone_handle 2007-05-10 Arne Caspari * libucil/colorspace.c (y8002y420): new xform (y8002y422): new xform (bgr242uyvy): fix wrong rgb order (rgb24toyuv420p): new xform (yuv420ptorgb24): new xform (bgr24torgb24): new xform (rgb32torgb24): new xform * cpi/v4l/v4l.c (v4l_enumerate_devices): fix: v4l devices where not detected 2007-05-08 Arne Caspari * libucil/ucil_theora.c (ucil_theora_encode_thread): added encode callback function 2007-04-26 Arne Caspari * include/unicap.h: use gtk-doc for documentation 2007-04-20 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_reenumerate_properties): query private properties also 2007-04-17 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_new_frame_callback): allow applications to register a new_frame_callback 2007-04-12 Arne Caspari * cpi/v4l/v4l.c (v4l_enumerate_devices): fix: enumerate all devices even if device files have non-continuous numbering * cpi/v4l2/v4l2.c (v4l2_enumerate_devices): fix: enumerate all devices even if device files have non-continuous numbering 2007-04-11 Arne Caspari * libucil/ucil_theora.c (ucil_theora_worker_thread): eos handling 2007-03-29 Arne Caspari * cpi/dcam/dcam.c (dcam_capture_start): Support speeds > S800 * cpi/v4l2/v4l2.c (cpi_register): fix: get_current_format 2007-03-28 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_capture_start): fix: return value of ioctl was misinterpreted as error 2007-03-23 Arne Caspari * libunicapgtk/unicapgtk_video_format_selection.c (size_changed_cb): fix: size change was not set correctly * cpi/v4l/v4l.c (wait_buffer): fix: timestamp information * cpi/vid21394/vid21394_base.c (_vid21394_new_iso_handler): fix: timestamp information * cpi/dcam/dcam_capture.c (dcam_dma_capture_thread): fix: copy timestamp information * libunicapgtk/display_backends/backend_gtk.c (backend_get_image_data): fix: copy timestamp information * libucil/ucil_theora.c (ucil_theora_encode_thread): implemented fill_frames * libunicapgtk/display_backends/backend_xv.c (backend_get_image_data): fix: copy timestamp information * libunicapgtk/unicapgtk_video_display.c (timeout_cb): fix: copy timestamp information * libucil/ucil_theora.c (ucil_theora_encode_frame): fix: copy timestamp * cpi/v4l2/v4l2.c (v4l2_capture_thread): fix: missing timestamp information when using callbacks 2007-03-22 Arne Caspari * libunicapgtk/unicapgtk_device_property.c (create_mapping): fix: uninitialized nmappings * configure.in: arg-enable for avcodec and ogg/theora * cpi/Makefile.am (DIST_SUBDIRS): remove not working 'remote' cpi 2007-03-21 Arne Caspari * libucil/video_file.c: added video recording/playback functionality * libucil/mpeg.c: added avcodec support * libucil/ucil_theora.c: added theora support * libucil/colorspace.c (uyvytoyuv420p): fixed (rgb322uyvy): new conversion (bgr242uyvy): new conversion (rgb242uyvy): new conversion 2007-03-16 Arne Caspari * include/unicap_status.h (STATUS_UNSUPPORTED_CODEC): added UNSUPPORTED_CODEC and FILE_NOT_FOUND 2007-03-09 Arne Caspari * libucil/colorspace.c (ucil_convert_buffer): fix: copy buffers with same fourccs 2007-03-05 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_capture_thread): fix(?) to avoid blocking with bt878 2007-02-21 Arne Caspari * libucil/colorspace.c (ucil_convert_buffer): direct copy of buffers not needing conversion * cpi/v4l2/v4l2.c (v4l2_capture_thread): fix potential blocking 2007-02-05 Arne Caspari * libunicapgtk/unicapgtk_video_format_selection.c (size_changed_cb): emit signal with correct format * libunicapgtk/display_backends/backend_gtk.c (scale_image): implemented image scaling 2007-01-23 Arne Caspari * libunicapgtk/display_backends/backend_xv.c (backend_init): use widgets window again 2007-01-22 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (set_backend): fixed small memleak 2007-01-16 Arne Caspari * libunicapgtk/unicapgtk.c: replacement for g_keyfile_set_double * libucil/font.c: use pango for text rendering * libucil/draw.c: yuy2 support * cpi/dcam/dcam_property.c: support for AF/BF strobe modes * cpi/dcam/dcam.h (enum dcam_property_enum): support for AF/BF strobe modes * libunicapgtk/unicapgtk_video_display.c: support for new backend drawing scheme * libunicapgtk/display_backends/backend_gtk.c (create_overlay_window): draw in our own window * libunicapgtk/display_backends/backend_xv.c (create_overlay_window): draw in our own window 2007-01-09 Arne Caspari * libunicapgtk/unicapgtk.c (unicapgtk_key_file_set_double): added 2007-01-08 Arne Caspari * cpi/dcam/dcam_property_table.h (_dcam_properties): added strobe properties * cpi/dcam/dcam_property.c (dcam_get_strobe_polarity_property): added strobe properties * libucil/font.c (draw_bitmap): added text drawing functions 2007-01-07 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (da_expose_event): fix: check if backend is present * libunicapgtk/colorspace.c (grey2rgb24): new conversion * libunicapgtk/cs_xfm.c (cs_xfm_new_pixbuf): fix: memcpy * libucil/ucil.c (ucil_get_colorspace_from_fourcc): new function * libucil/draw.c (ucil_set_pixel_alpha): new function (ucil_draw_circle): new function * cpi/v4l/v4l.c (v4l_capture_thread): implemented threaded capturing (v4l_set_event_notify): implemented unicap event handling (v4l_enumerate_formats): changed RGB24 --> BGR24 since this seems to be the correct ordering (v4l_enumerate_properties): set flags correctly made all functions static * libunicapgtk/colorspace.c (y4202rgb24): added new conversion (y4202uyvy): added new conversion (y4202yuy2): added new conversion (bgr242rgb24): added new conversion 2007-01-02 Arne Caspari * libunicapgtk/display_backends/backend_gtk.c (backend_lock): implemented locking * libunicapgtk/display_backends/backend_xv.c (backend_lock): implemented locking * libunicapgtk/unicapgtk_video_display.c (da_expose_event): correct handling of predisplay signal 2006-12-11 Arne Caspari * include/unicap.h (enum _unicap_buffer_type): fixed compile issue * cpi/vid21394/vid21394_base.c: implemented threaded capturing * cpi/dcam/dcam_property.c (dcam_set_frame_rate_property): fix: set frame rate only worked when streaming was on * cpi/dcam/dcam_busreset.c (dcam_device_removed_event): rename DEVICE_LOST -> DEVICE_REMOVED 2006-11-27 Arne Caspari * libunicapgtk/unicapgtk_video_display.c: use unicap callbacks 2006-11-24 Arne Caspari * cpi/vid21394/vid21394_cpi.c (cpi_get_format): use unicap_copy_format instead of memcpy (cpi_set_format): add SYSTEM_BUFFERS 2006-11-20 Arne Caspari * libunicapgtk/unicapgtk_video_format_selection.h: missed get_handle prototype 2006-11-15 Arne Caspari * debian/control (Description): added libucil-0 and libucil-dev 2006-11-14 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_format): initialize correctly even when no unicap_handle is associated with the display 2006-11-13 Arne Caspari * libunicapgtk/unicapgtk.c (unicapgtk_key_file_get_double): add replacement for g_key_file_get_double, removes requirement for glib-2.12 2006-11-10 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (timeout_cb): thread awareness * libunicapgtk/display_backends/backend_xv.c (backend_init): load configuration data from user home directory * cpi/v4l2/v4l2.c (v4l2_capture_thread): new threaded capture mechanism * libunicap/unicap.c (unicap_event_callback): new event system * cpi/dcam/dcam_capture.c (dcam_dma_capture_thread): fire a new frame event even when no user-buffer is queued * libunicap/unicap.c (unicap_open): clone handle for event_notify 2006-10-30 Arne Caspari * libunicapgtk/display_backends/backend_xv.c (backend_init): look for other Xv adaptors if the first one is in use or not suitable (backend_init): small memleak fix 2006-10-25 Arne Caspari * libucil/Makefile.am: Added libucil, a library for simple image processing tasks * libunicapgtk/libunicapgtk.pc.in (Version): Set correct version information * libunicap/libunicap.pc.in (Version): Set correct version information 2006-10-23 Arne Caspari * libunicapgtk/display_backends/backend_xv.c (backend_init): also look in userconf dir for unicapgtk.conf * libunicapgtk/unicapgtk_video_display.c (set_backend): also look in userconf dir for unicapgtk.conf 2006-10-20 Arne Caspari * libunicapgtk/unicapgtk.c: added functionality to store and restore the device state * libunicapgtk/unicapgtk_property_dialog.c (save_device_defaults): Added functionality to store/restore device defaults 2006-10-12 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (unicapgtk_property_dialog_reset): destroy all widgets in the notebook instead of just removing the pages * libunicapgtk/unicapgtk_video_format_selection.c (unicapgtk_video_format_selection_set_handle): Do not try to open NULL handle * libunicapgtk/unicapgtk_property_dialog.c (unicapgtk_property_dialog_set_handle): Do not try to open NULL handle 2006-10-04 Arne Caspari * libunicap/unicap.c: renamed union semun -> union semun_linux to avoid conflict on OSX * libunicapgtk/display_backends/Makefile.am (BACKENDS_LIB): do not build backends when unicapgtk is disabled 2006-10-01 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (append_pages): fix memleak * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_destroy): fix memleak * libunicapgtk/unicapgtk_video_format_selection.c (unicapgtk_video_format_selection_destroy): fix memleak * libunicapgtk/display_backends/backend_xv.c (backend_destroy): Fix memleak 2006-09-25 Arne Caspari * libunicapgtk/unicapgtk_device_property.c: map shutter values to human readable strings 2006-09-18 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c: continuously update property widgets * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_stop): removed 'display not running' message 2006-09-14 Arne Caspari * libunicapgtk/display_backends/backend_xv.c (backend_expose_event): redraw image in expose ( fixes pause ) * libunicapgtk/unicapgtk_device_selection.c (unicapgtk_device_selection_set_label_fmt): added * fixed: key file not loaded in xv backend 2006-08-28 Arne Caspari * cpi/thing/thing.c: initialize cpi_data structure, fixes memory corruption * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_start): fix: use USER_BUFFER when SYSTEM_BUFFER is not available 2006-08-22 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_start): improved error handling 2006-08-21 Arne Caspari * libunicapgtk/unicapgtk_video_display.c: Changed event mask for drawing_area to allow button press events fix: set output width and height in backend_xv when scale_to_fit==TRUE 2006-08-18 Arne Caspari * libunicapgtk/unicapgtk_device_selection.c (device_combo_box_changed): added a device change signal * examples/unicapgtk/smallapp/smallapp.c (create_application_window): changed window default size (create_application_window): small layout changes * libunicapgtk/unicapgtk_video_display.c: Added functionality to load backend merit from keyfile 2006-08-17 Arne Caspari * libunicapgtk/colorspace.c: performance improvements for yuv->rgb24 and yuv->rgb32 * cpi/v4l2/v4l2.c (v4l2_wait_buffer): fixed memleak * libunicapgtk/unicapgtk_property_dialog.c: changed from treeview to notebook layout 2006-08-02 Arne Caspari * include/unicap.h: fixes for SYSTEM_BUFFERS * cpi/v4l2/v4l2.c (v4l2_reenumerate_formats): better handling of v4l2_crop handling of system buffers * cpi/dcam/dcam_capture.c: support for SYSTEM_BUFFERS * cpi/dcam/dcam.c (cpi_set_format): support for SYSTEM_BUFFERS * examples/unicapgtk/smallapp/smallapp.c (menu_entries): removed view menu removed zoom functionality * cleaned up unicapgtk example directory * examples/unicapgtk/callback/callback.c: fix: open by device * libunicapgtk/display_backends/backend_gtk.c: backend for video display using GTK/GDK * libunicapgtk/display_backends/backend_xv.c: backend for video display using Xv extensions * libunicapgtk/unicapgtk_video_display.c: implemented modules for display backend * cpi/v4l2/v4l2.c (v4l2_reenumerate_properties): fix: remove video norm property for devices without a video norm (queue_buffer): pre-queue buffers when live video is not yet started 2006-06-27 Arne Caspari * libunicapgtk/unicapgtk_video_display.c: change resize behaviour to scale-to-fit ( patch by Sven Neumann ) use GBOOLEAN instead of C-int ( patch by Sven Neumann ) * libunicapgtk/colorspace.c: fix endianess issue * cpi/v4l2/v4l2.c: added video norm property 2006-06-13 Arne Caspari * removal of deprecated GTK functions ( patch by Sven Neumann ) * fix for compiler warnings ( patch by Sven Neumann ) 2006-06-12 Arne Caspari * libunicapgtk/unicapgtk_property_dialog.c (selection_changed_cb): crash fix ( patch from Sven Neumann ) * libunicapgtk/unicapgtk_device_property.c: fix: incorrect sensitivity handling of auto check box ( patch from Sven Neumann ) * libunicapgtk/unicapgtk_property_dialog.c: HIG compliance patches from Sven Neumann * libunicapgtk/unicapgtk_video_display.c: applied patches from Sven Neumann: dropout color changed to blue; container changed to GtkAspectFrame; 2006-06-09 Arne Caspari * cpi/v4l2/v4l2.c (v4l2_enum_inputs): fix bug: list of video input strings was static 2006-05-12 Arne Caspari * libunicapgtk/xv.c: fix wrong includes * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_start): check whether color format can be displayed (unicapgtk_video_display_class_init): add USE_XV property ( Sven Neumann ) 2006-05-11 Arne Caspari * Makefile.am (EXTRA_DIST): added debian control files ( thanks Sven Neumann! ) * examples/c/sdl_display/sdl_display.c (main): code cleanup (main): try to use right overlay for selected fourcc * cpi/v4l2/v4l2.c (fourcc_bpp_map): add/fix: bpp for video formats ( Frank Loemker ) (v4l2_capture_stop): fix: check whether capture_start was called before freeing buffers and shutting down the stream * cpi/v4l/v4l.c (cpi_open): initialize format and property table ( Frank Loemker ) (cpi_reenumerate_formats): fix: video_picture structure was not initialized ( Frank Loemker ) (cpi_enumerate_formats): fix fourcc: Y41P to 411P ( thanks Frank Loemker ) (cpi_queue_buffer): fix: buffer handling ( Frank Loemker ) * cpi/v4l2/v4l2.c (build_format_size_table): check for supported video format sizes 2006-04-12 Arne Caspari * libunicapgtk/colorspace.c (unicapgtk_cs_get_converter_from_fourcc): more flexible handling of colorspace transform functions 2006-04-09 Arne Caspari * cpi/vid21394/vid21394_base.c (vid21394_open): fix memleak 2006-04-06 Arne Caspari * libunicapgtk/xv.c: code cleanup * libunicapgtk/unicapgtk_video_format_selection.c (unicapgtk_video_format_selection_init): Better layout * libunicapgtk/unicapgtk_video_display.c: Better Xv handling * libunicapgtk/unicapgtk_video_display.c (new): automatically set biggest available image size * libunicapgtk/unicapgtk_device_selection.c: new widget contributed by JPK Instruments AG * libunicapgtk/colorspace.c (grey2uyvy): added grey->uyvy conversion to use Xv for monochrome video (uyvy2rgb24): optimizations * examples/unicapgtk/unicapgtk_smallapp/unicapgtk_smallapp.c: use new device_selection widget * examples/device_specific/dfg1394/sdl_display/sdl_display.c: removed bogus #include * cpi/vid21394/visca.c (visca_set_ae_mode): fix: signed vs. unsigned char * cpi/vid21394/vid21394_base.c: code cleanup * cpi/dcam/dcam.c: code cleanup * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_start): use YUY2 instead of UYVY 2006-04-05 Arne Caspari * libunicapgtk/unicapgtk_video_format_selection.c: applied patch from Sven Neumann: Memory leak fix * libunicapgtk/xv.c (xv_init): use fourcc even if chars are not printable 2006-03-24 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_destroy): implement GtkObject::destroy and chain up instead of connecting to our own "destroy" signal ( thanks Sven Neumann ) (unicapgtk_video_display_set_property): added construct-only property "disable-xv" to explicitely disable use of the XVideo extension ( thanks Sven Neumann ) (display_xv): check frontbuffer pointer before accessing it ( thanks Sven Neumann ) 2006-03-21 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (new): better default for video format size * libunicapgtk/colorspace.c (grey2uyvy): endianess fix ( thanks Sven Neumann ) (uyvy2rgb24): Optimizations * cpi/dcam/dcam_capture.c (_dcam_dma_setup): check for new naming convention of video1394 device file 2006-03-14 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_set_handle): fix: ugtk->device not updated after display_set_handle 2006-03-13 Arne Caspari * libunicapgtk/xv.c (xv_update_image): allow image dimensions to be set * libunicapgtk/xv.c: cleanup 2006-03-10 Arne Caspari * libunicapgtk/unicapgtk_device_selection.c: Added device selection windget ( contributed by JPK instruments ) 2006-03-08 Arne Caspari * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_get_format): add get_format function 2006-02-17 Arne Caspari * examples/unicapgtk/unicapgtk_smallapp/unicapgtk_smallapp.c (create_application_window): Use menu_bar instead of buttons 2006-02-15 Arne Caspari * libunicap/unicap.c (unicap_lock_stream): Use semaphores instead of file locking ( experimental ) * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_start): Added simple GREY->YUV conversion and use YUV overlay for Y800 images 2006-02-14 Arne Caspari * examples/unicapgtk/unicapgtk_smallapp/unicapgtk_smallapp.c (create_device_menu): use unicap_is_stream_locked: saves one unicap_open * libunicap/unicap.c (unicap_is_stream_locked): new function to check stream lock without the need to open the device * libunicapgtk/unicapgtk_video_format_selection.c (new): Better handling of devices lacking a video format * cpi/dcam/dcam.h: added performance timing helper * cpi/dcam/dcam.c (cpi_open): fix bug: command_regs_base used before initialized ( lead to long startup times for IIDC cameras) 2006-02-04 Arne Caspari * libunicapgtk/unicapgtk_video_format_selection.h (UNICAPGTK_VIDEO_FORMAT_SELECTION): Fix: copy/paste error: wrong macro definitions ( thanks Sven Neumann ) * cpi/dcam/dcam_functions.c (_dcam_check_compat_fast): Fix: detect iSight camera again 2006-02-03 Arne Caspari * libunicapgtk/libunicapgtk.pc.in (Libs): Included XLib dependencies in linker flags ( Sven Neumann ) (prefix): prefix now set by 'configure' ( Sven Neumann ) * libunicap/libunicap.pc.in (prefix): prefix now set by 'configure' ( Sven Neumann ) (Libs): librt dependency added to linker flags ( Sven Neumann ) * configure.in (GTK_PACKAGE_LIBS): Removed GConf dependency ( patch from Sven Neumann ) * libunicapgtk/unicapgtk_video_display.c (unicapgtk_video_display_start): fixed crash when changing video formats ( bug #1422614 2006-01-23 Arne Caspari * libunicapgtk/unicapgtk_device_property.c (unicapgtk_device_property_set_label): fixed obvious bug * libunicapgtk/unicapgtk_xv.h (struct _xv_handle): fixed incorrect struct _xv_handle definition * libunicapgtk/unicapgtk_property_dialog.h: added missing include for gtkwindow.h 2006-01-09 Arne Caspari * cpi/dcam/dcam_functions.c (_dcam_read_register): do not retry when error condition is "invalid arg" (_dcam_get_vendor_name_leaf_address): directly work on unit_dir_address to avoid unneccessary register reads (_dcam_get_model_name_leaf_address): directly work on unit_dir_address to avoid unneccessary register reads (_dcam_check_compat_fast): search for spec_id and sw_version at fixed offsets to speed up device detection (_dcam_is_compatible): added shortcut for devices that only have 1 unit directory * libunicapgtk/unicapgtk_property_dialog.c (unicapgtk_property_dialog_init): made GtkPaned widget resizable (unicapgtk_property_dialog_init): added some horizontal spacing * libunicapgtk/unicapgtk_device_property.c (range_value_changed_cb): set correct flags on slider movement 2006-01-04 Arne Caspari * cpi/vid21394/visca.c (visca_htofla): Endianess conversion 2006-01-03 Arne Caspari * cpi/vid21394/visca.c: fix endianess issue with serial communication 2006-01-03 Arne Caspari * cpi/dcam/dcam.c (cpi_open): send camera initialize command and wait for completion * libunucapgtk/device_property: fix: change widget sensitive state when auto button is clicked 2005-12-29 Arne Caspari * libunicapgtk/device_property: use combo_box instead of option_menu * libunicapgtk/device_property: add redraw function * cpi/dcam: fix for trigger property 2005-10-23 Arne Caspari * unicap.c: Fixed memleak: handle->ref_count was not freed when ref_count == 0 2005-10-12 Arne Caspari * cpi/dcam: support absolute values for shutter * Frank Loemkers patches: * cpi/dcam: fix access to uninitialized raw1394 userdata * cpi/dcam: fix count value for reenumerate_properties * cpi/dcam: look for /dev/video1394 if /dev/video1394/n is not available * cpi/vid21394: add missing prototypes * cpi/v4l2: property type in reenumerate_properties was not set * cpi/vid21394: get property for video source and video norm was incorrect * cpi/vid21394: fix in cpi_open: incorrect use of raw1394_new_handle_on_port 09-28-2005 - libunicapgtk/property_dialog: update window title when device changes - examples/unicapgtk_smallapp: disabled menu items for devices which stream is locked - examples/unicapgtk_smallapp: added 'rescan' menu item 09-26-2005 - libunicap: implemented locking mechanism for multiple devices 09-15-2005 - cpi/vid21394: cleanup 09-13-2005 - cpi/vid21394: fix for multiple cards/devices support - cpi/dcam: fix for multiple cards/devices support - libunicapgtk/video_format_selection: added "new_by_device" and "set_device" - libunicapgtk/video_display: fix "set_device" 09-08-2005: - unicapgtk/device_property: deactivate slider when auto is active 09-07-2005 - cpi/vid21394: fix get_property "firmware version" - cpi/vid21394: fix(?) support multiple IEEE1394 cards 09-06-2005 - unicapgtk/videoformatselection: added get_format 08-26-2005 - cpi/dcam: added absolute value support for shutter 08-24-2005 - libunicapgtk/property_dialog: add reset function - libunicapgtk/property_dialog: fix memory leak ( property list not freed on widget_destroy ) 08-23-2005 - libunicapgtk/property_dialog: made all labels same length - libunicapgtk/property_dialog: set window type hint to DIALOG 08-22-2005 - cpi/dcam: add timeout value - cpi/dcam: fix: capture_thread_quit flag was not removed after capture_stop 08-19-2005 - libunicap: Changed RTLD_LAZY to RTLD_NOW - cpi/v4l2: fixed unitialized format structures ( patch from Frank Loemker ) - cpi/v4l2: replaced memcpy with unicap_copy_property/unicap_copy_format - cpi/v4l2/cpi_reenumerate_properties: fixed : incorrect number of properties returned ( patch from Frank Loemker ) - cpi/vid21394: fix raw1394 handle leaks ( patch from Frank Loemker ) - cpi/vid21394: fix brightness/contrast range ( patch from Frank Loemker ) - cpi/dcam: wait for capture thread to terminate ( patch from Frank Loemker ) - cpi/dcam: fix : the DMA buffer was returned instead of copied 08-18-2005 - code cleanup 08-17-2005 - cpi/dcam: when changing frame rate property, capture is now stopped and restarted - cpi/vid21394: when changing video mode, capture is now stopped and restarted 08-17-2005 - cpi/dcam: fixed bug in DMA capture ( wrong offsets for formats with vmmapped buffer size different to frame size ) - cpi/dcam: changed some property categories - libunicapgtk/colorspace.c: added code for Y411 - libunicapgtk/property_dialog: added missing property_change signal handler - cpi/dcam: fixed property flags and flags_mask 08-14-2005 - cpi/vid21394: improved and debugged VISCA support - cpi/vid21394: revised property settings 08-02-2005 - cpi/dcam: individual dcam_get_property/dcam_set_property functions for each property - cpi/dcam: specified property relations 07-29-2005 - configure.in & Makefile.am: Changed automake files to use AM_CONDITIONAL instead of conditional AC_SUBST 07-28-2005 - cpi/vid21394: 21cf04 detection 07-27-2005: - cpi/dcam: dcam_property_table: made more readable 07-26-2005 - cpi/vid21394: added VISCA support 07-15-2005 - cpi/dcam: DMA capture now runs in seperate thread 07-13-2005 - cpi/vid21394: fixed timeout function ( was waking up too fast ) - fixed timeout thread cleanup 06-21-2005 - configure.in: 'tests' are only build when libunicapxml is enabled ( dependency problem ) - configure.in: vid21394 bootload support is now a --enable option ( default: disable ) 06-03-2005 - configure.in: Fixed versioning information - tests: added test for unicapxml - unicapxml: implemented and tested functionality for unicap_property; unicap_format and unicap_device 05-25-2005 - configure.in: added provisions for unicapxml - libunicapxml: imported code for unicapxml - libunicapgtk/unicapgtk_video_display: implemented cropping - examples: added 'device_specific' sample for Dxx41f02 - examples/unicapgtk: added example for cropping 05-18-2005 - configure.in: commented out standard tests for faster configure 05-11-2005 - libunicap/unicap.c: set_filter_remote function implemented - cpi/remote.c: added 05-04-2005 - libunicap/unicap.c: New function: unicap_get_device - libunicapgtk/unicap_property_dialog: New widget - libunicapgtk/unicap_device_property: changed widget layout 05-02-2005 - libunicap/Makefile.am: added dependency to "libunicap.pc" - libunicapgtk/Makefile.am: added dependency to "libunicapgtk.pc" 04-22-2005 - libunicapgtk/videoformatselection: replaced deprecated gtk_option_menu with gtk_combo_box 04-21-2005 - libunicapgtk/videodisplay: added pause function - libunicapgtk/videodisplay: display still image when paused - examples/unicapgtk_smallap: replaced deprecated gtk_option_menu with combo_box - libunicapgtk/videodisplay: added set_handle function to change device - libunicapgtk/videoformatselection: added set_handle function to change device 04-20-2005 - libunicapgtk/videoformatselection: added missing signal emission when no sizes are present for a format - examples/unicapgtk_smallapp: added missing callback for property changes - libunicapgtk/videodisplay: fixed memleak when a buffer is colour converted 04-19-2005 - libunicapgtk/videodisplay: fix for display_timeout bug fix - libunicapgtk/videodisplay: fixes for cleanup when widget gets destroyed - cpi/dcam: fixes for poll buffer; dequeue buffer 04-18-2005 - cpi/dcam: check for UNICAP_BUFFER_TYPE_SYSTEM/memcpy on TYPE_USER - cpi/v4l: mmap buffers for UNICAP_BUFFER_TYPE_SYSTEM/memcpy on TYPE_USER - cpi/v4l2: mmap buffers for UNICAP_BUFFER_TYPE_SYSTEM/memcpy for TYPE_USER 04-14-2005 - cpi/dcam: make poll_buffer work. This fixes not working unicapgtk_videodisplay for dcam cameras 04-13-2005 - cpi/vid21394: code cleanup - cpi/vid21394: disable "enter bootload" and rs232 functions for default build - libunicapgtk/videodisplay: fixed severe bug: old display_timeout functions where not removed - libunicapgtk: added missing config.h includes - examples/c/raw_image: store original image buffer pointer to free correct one when cpi returns a bogus buffer ptr 04-12-2005 - libunicapgtk: removed some debug output junk - libunicap: fixed bug in device model name matching 04-11-2005 - examples/c/sdl_display: fixed bugs: buffer_size not set; ask for video format size - examples/c/raw_image: fixed: buffer_size not set 04-11-2005 - added new example for DFG/1394 - cleaned up the dist package a bit - changed bpp of V4L_PALETTE_RAW to 8 04-07-2005 - examples/raw_image: fixed compile issue; more error checking; output PNM headers for image data - configure: added --enable-debug- options to enable verbose debug output - reorganized the example directory 04-04-2005 - cpi/vid21394: final changes for libraw1394 >= 1.1.0 - cpi/dcam: fixes for white balance and property flags 09-03-2005 - cpi/dcam: changes to support libraw1394 >= 1.1.0 versions - cpi/vid21394: changes to support libraw1394 >= 1.1.0 versions - configure: changes to support libraw1394 >= 1.1.0 versions - added example: device_property - cpi/dcam: input/output queue initializion fix - libunicapgtk/unicapgtk_device_property: added a sanity check for properties that might crash GTK 09-03-2005 - cpi/dcam: fixed video format table sizes - cpi/vid21394: video format size fixes 30-01-2005 - cpi/dcam: trigger mode - libunicapgtk/unicapgtk_smallapp: added error message when no device found; fixes - libunicapgtk/cs_xfm.c: removed a memcpy - libunicapgtk/unicapgtk_videodisplay.c: workaround for gtk hang - libunicapgtk/unicapgtk_videodisplay.c: change format fixes - renamed unicapgtk_videodisplay ==> unicapgtk_video_display - added "unicapgtk.h" include file for all unicapgtk includes - libunicapgtk/video_format_selection: Fix for menu not displaying correct format sometimes - libunicapgtk/video_format_selection: Emit a format change signal when color format changes - unicapgtk example changes for unicapgtk_video_display rename - unicapgtk examples now include only "unicapgtk.h" - renamed unicapgtk_deviceproperty ==> unicapgtk_device_property - libunicapgtk/unicapgtk_video_display: Fix for crash when no device found 11-16-2004 - cpi/thing: fixes - libunicapgtk/unicap_video_format_selection: fixes - examples/unicapgtk_smallapp: added callbacks for video format selection - examples/unicap--: C++ wrapper classes for libunicap - include/unicap.h: Changed C++ keyword "class" to "klass" ( will change name again on next release! ) - cpi/dcam: neccessary changes for new "unicap.h" - cpi/v4l: neccessary changes for new "unicap.h" - cpi/v4l2: neccessary changes for new "unicap.h" - libunicap/*: neccessary changes for new "unicap.h" 11-01-2004 - cpi/dcam: Code cleanup - cpi/dcam: fixed possible endianess issue - cpi/dcam: added property for direct register access - libunicapgtk/unicap_video_format_selection: New widget - examples/unicapgtk_smallapp: enhanced example for video_format_selection 10-25-2004 - unicap.h: added extern "C" 10-13-2004 - libunicapgtk/unicap_deviceproperty.c: Added support for value lists 10-08-2004 - libunicapgtk/unicap_deviceproperty.c: Added support for menu selections 10-05-2004 - cpi/dcam: Added slowdown value cope with slow cameras - cpi/vid21394: New command for experimental firmware - libunicapgtk: "auto" and "one push" buttons should now work - Added and updated some documentation 09-07-2004 - cpi/dcam: Changed bandwidth control: Per default ignore bandwidth set UNICAP_DCAM_BW_CONTROL to "enable" to re-enable BW control - cpi/dcam: start a watchdog thread to avoid ieee1394 hangs - cpi/dcam: various fixes - cpi/vid21394: removed bitops; this fixes some compile problems on RH fedora core ( and maybe others ) - cpi/vid21394: recognize devices with VISCA firmware extension - cpi/v4l2: "video source" property - cpi/v4l2: various bugfixes ( correct bpp reporting, correct number of properties returned from enum_properties ) - libunicapgtk/unicapgtk_deviceproperty.c: added an expander for "auto"/"one push"... properties - libunicapgtk/unicapgtk_deviceproperty.c: first try to let the controls do something usefull ( ie. set_property ) - fixed the 'make clean' issue of the configure script - enhanced the configure script ( you can now say --enable-[some cpi] ) - enhanced the configure script: build of unicapgtk is now optional - configure script: removed unused dependencies ( SDL ) - examples/Makefile: removed xv_display from subdirs ( no own makefile ) - NEW example: sdl_image_saving: saves images using jpeglib - NEW README for examples - disabled debug output per default 08-09-2004 - Added missing files/directories to dist - fixed various compile issues 08-06-2004 - renamed status.h -> unicap_status.h ** Please change all old programs to use unicap_status.h - added autoconf/automake scripts - removed strange 'dbg_alloc' debug statements - cpi/dcam: fix for 1024x768 UYVY format definition - cpi/v4l: link with pthread ( sem_init and co. ) - cpi/v4l2: link with pthread ( sem_init and co. ) - cpi/thing: link with pthread ( sem_init and co. ) 07-11-2004 - cpi/dcam: update properties on reenumeration - cpi/dcam: fix for whitebalance property - cpi/dcam: fix for frame rate property - cpi/vid21394: functionality for experimental firmware - cpi/vid21394: fixed bug in video format definitions - cpi/vid21394: fixed bug in video source selection - cpi/vid21394: return a status on set_property - examples/device_info: print range/value for each property - examples/sdl_display.c: added sdl_rgb_display ( not finished ) - libunicap: added unicap_clone_handle - libunicapgtk: severall fixes - libunicapgtk: added unicapgtk_deviceproperty 06-28-2004 - unicap_clone_handle added - unicap_gtk widget known as libunicapgtk - added unicapgtk samples: unicapgtk_simple, unicapgtk_cp and unicapgtk_smallapp 05-10-2004 - added xv_display example - started work on unicap_gtk widget 05-07-2004: - added sdl_display example 05-06-2004: - added examples directory - added raw_image example - added device_info example 04-29-2004: - missing closedir() in cpi loading function 04-26-2004: - fixed bug leading to a crash while loading cpi plugins libunicap/cpi/0000755000175000017500000000000013164711411014030 5ustar zmoelnigzmoelniglibunicap/cpi/vid21394/0000755000175000017500000000000013164711411015215 5ustar zmoelnigzmoelniglibunicap/cpi/vid21394/visca.h0000644000175000017500000000276613164711411016506 0ustar zmoelnigzmoelnig#ifndef __VISCA_H__ #define __VISCA_H__ /* unicap Copyright (C) 2004 Arne Caspari ( arne_caspari@users.sourceforge.net ) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ enum visca_camera_type { VISCA_CAMERA_TYPE_NONE = 0, VISCA_CAMERA_TYPE_FCB_IX47, VISCA_CAMERA_TYPE_UNKNOWN }; typedef enum visca_camera_type visca_camera_type_t; unicap_status_t visca_reenumerate_properties( vid21394handle_t vid21394handle, int *count ); unicap_status_t visca_enumerate_properties( unicap_property_t *property, int index ); unicap_status_t visca_set_property( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_property( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_check_camera( vid21394handle_t vid21394handle, visca_camera_type_t *type ); #endif//__VISCA_H__ libunicap/cpi/vid21394/Makefile.am0000644000175000017500000000143613164711411017255 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in INCLUDES = -I../include -I../../include @LIBRAW1394_PACKAGE_CFLAGS@ -I. -I../../common if ENABLE_STATIC_CPI noinst_LTLIBRARIES = libvid21394.la libvid21394_la_LIBADD = @LIBRAW1394_PACKAGE_LIBS@ @PTHREAD_LIBS@ -L../../common -lucutils else libcpi_LTLIBRARIES = libvid21394.la libvid21394_la_LIBADD = @LIBRAW1394_PACKAGE_LIBS@ @PTHREAD_LIBS@ -L../../src/.libs/ -lunicap -L../../common -lucutils endif libcpidir = $(libdir)/unicap$(pkg_version)/cpi libvid21394_la_LDFLAGS = -module -avoid-version libvid21394_la_SOURCES = 1394util.c \ Fcp.h \ vid21394.h \ vid21394_base.c \ vid21394_base.h \ vid21394_cpi.c \ vid21394_cpi.h \ visca.c visca.h visca_private.h\ visca_property_table.h libvid21394_la_CFLAGS = -fno-strict-aliasinglibunicap/cpi/vid21394/vid21394_base.c0000644000175000017500000014611713164711411017552 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include // for ntohl #include //for nanosleep #include // Old .pc descriptions had .../libraw1394 in their path. #if RAW1394_1_1_API #include #include #else #include #include #endif /* #include "kernel-video1394.h" */ #include "video1394.h" #include "vid21394_base.h" #include "1394util.h" #include "Fcp.h" #include #include "unicap_status.h" #if VID21394_DEBUG #define DEBUG #endif #include #define DMA 1 int vid21394_video_mode_sizes[]= { 0x0, 320*240*2, // QVGA 4:2:2 640*480+640*240, // VGA 4:1:1 640*480*2, // VGA 4:2:2 320*240, // QVGA 8:0:0 640*480, // VGA 8:0:0 320*240+320*120, // QVGA 4:1:1 768*576, // PAL 8:0:0 768*576+768*288, // PAL 4:1:1 768*576*2 // PAL 4:2:2 }; int vid21394_video_mode_line_lengths[]= { 0x0, 320*2, // QVGA 4:2:2 640+320, // VGA 4:1:1 640*2, // VGA 4:2:2 320, // QVGA 8:0:0 640, // VGA 8:0:0 320+160, // QVGA 4:1:1 768, // PAL 8:0:0 768+384, // PAL 4:1:1 768*2 // PAL 4:2:2 }; static void *_vid21394_timeout_thread( void *arg ); static int _vid21394_busreset_handler( raw1394handle_t raw1394handle, unsigned int generation ); static int _vid21394_fcp_handler( raw1394handle_t handle, nodeid_t nodeid, int response, size_t length, unsigned char *data ); static int _vid21394_send_fcp_command( vid21394handle_t vid21394handle, unsigned long long fcp_command, int sync_bit, unsigned long *response ); static unicap_status_t _vid21394_send_fcp_command_ext( vid21394handle_t vid21394handle, unsigned long long fcp_command, unsigned long extra_quad, int sync_bit, unsigned long *response ); static unicap_status_t _vid21394_send_fcp_command_new( vid21394handle_t vid21394handle, unsigned long long fcp_command, unsigned long sync_bit, void *data, size_t data_length, void *response, size_t *response_length ); static int _vid21394_find_device( unsigned long long sernum, int *port, int *node ); enum vid21394_byte_order { VID21394_BYTE_ORDER_UYVY = 0x0, VID21394_BYTE_ORDER_YUYV = 0x1, VID21394_BYTE_ORDER_VYUY = 0x2, VID21394_BYTE_ORDER_YVYU = 0x3 }; typedef enum vid21394_byte_order vid21394_byte_order_t; static unsigned long long prepare_fcp_command( unsigned int x ) { union fcp_command command; command.int32value[0] = ntohl( FCP_COMMAND ); command.int32value[1] = ntohl( x ); return command.int64value; } #ifdef DEBUG /* Dumps the data contained in the FCP response to stdout */ static void _vid21394_dump_fcp_data( int response, int length, unsigned char * data ) { /* TRACE( "got fcp %s of %d bytes:", */ /* (response ? "response" : "command"), length); */ /* while( length ) */ /* { */ /* printf(" %02x", *data); */ /* data++; */ /* length--; */ /* } */ /* printf("\n"); */ } #endif //DEBUG /* Handler for Fcp responses ( called from libraw1394 ) See raw1394.h */ static int _vid21394_fcp_handler(raw1394handle_t handle, nodeid_t nodeid, int response, size_t length, unsigned char *data) { unsigned long fcp_lo; unsigned char fcp_command_id; unsigned char fcp_status; int command_bit; vid21394handle_t vid21394handle = raw1394_get_userdata( handle ); #ifdef DEBUG _vid21394_dump_fcp_data( response, length, data ); #endif if( length < 8 ) { TRACE( "FCP response does not contain enough data!\n" ); return -1; } fcp_lo = *( ( unsigned long * ) data ); if( htonl( fcp_lo ) != FCP_COMMAND ) { TRACE( "FCP response does not match! quadlet #1's value is: %08lx, should be: %08x\n", fcp_lo, FCP_COMMAND ); return -1; } data += 4; // skip the first 4 bytes which are FCP_COMMAND fcp_command_id = *data; data++; fcp_status = *data; data++; if( fcp_command_id == ENTER_BOOTLOAD_MSG ) { command_bit = 31; } else { command_bit = fcp_command_id - 0x10; } if( sem_post( &vid21394handle->fcp_sync_sem[command_bit] ) < 0 ) { #ifdef DEBUG perror( "cpi/vid21394" ); #endif return STATUS_FAILURE; } vid21394handle->fcp_status[command_bit] = fcp_status; switch( fcp_command_id ) { case READ_I2C_BYTE_MSG: { /* TRACE( "Got response for READ_I2C_BYTE_MSG\n" ); */ vid21394handle->fcp_data = *(data+1); break; } case WRITE_I2C_BYTE_MSG: { /* TRACE( "Got response for WRITE_I2C_BYTE_MSG\n" ); */ break; } case SET_VIDEO_MODE_MSG: { /* TRACE( "Got response for SET_VIDEO_MODE_MSG\n" ); */ break; } case GET_FIRM_VERS_MSG: { /* TRACE( "Got response for GET_FIRM_VERS_MSG\n" ); */ vid21394handle->firmware_version = *data ; vid21394handle->firmware_version = vid21394handle->firmware_version << 8; vid21394handle->firmware_version += *(data+1) ; /* TRACE( "data: %x\ndata+1: %x\n", *data, *(data+1) ); */ /* TRACE( "pUserdata->firmware_version: %x\n", vid21394handle->firmware_version ); */ break; } case INPUT_SELECT_MSG: { /* TRACE( "Got response for INPUT_SELECT_MSG\n" ); */ break; } case CHK_VIDEO_LOCK_MSG: { /* TRACE( "Got response for CHK_VIDEO_LOCK_MSG\n" ); */ vid21394handle->fcp_data =( *(data+1) + ( *(data) << 8 ) ); break; } case ENA_ISOCH_TX_MSG: { /* TRACE( "Got response for ENA_ISOCH_TX_MSG\n" ); */ break; } case AVSYNC_EVERY_HLINE_MSG: { /* TRACE( "Got response for AVSYNC_EVERY_HLINE_MSG\n" ); */ break; } case READ_LINK_REG_MSG: { /* TRACE( "Got response for READ_LINK_REG_MSG\n" ); */ vid21394handle->fcp_data =( *(data+5) + ( *(data+4 ) << 8 ) + ( *(data+3 ) << 16 ) + ( *(data+2 ) << 24 ) ); break; } case WRITE_LINK_REG_MSG: { /* TRACE( "Got response for WRITE_LINK_REG_MSG\n" ); */ break; } case SERIAL_NUMBER_MSG: { /* TRACE( "Got response for SERIAL_NUMBER_MSG\n" ); */ break; } case SET_VIDEO_FREQUENCY_MSG: { /* TRACE( "Got response for SET_VIDEO_FREQUENCY_MSG\n" ); */ break; } case RS232_IO_MSG: { /* TRACE( "Got response for RS232_IO_MSG\n" ); */ if( length < 12 ) { /* TRACE( "FCP response does not contain enough data!\n" ); */ break; } if( ( *data+1 ) ) // if this was a read request { /* TRACE( "%d bytes of data\n", *(data+1)); */ memcpy( &vid21394handle->fcp_response[0], data+2, *data+1 ); vid21394handle->fcp_response_length = *(data+1 ); vid21394handle->fcp_status[command_bit] = fcp_status; } break; } case LINK_SPEED_MSG: { /* TRACE( "Got response for LINK_SPEED_MSG\n" ); */ break; } case ENTER_BOOTLOAD_MSG: { /* TRACE( "Got response for ENTER_BOOT_MODE_MSG\n" ); */ break; } }//switch return fcp_status; } /* Handles bus reset - All resources get freed upon a bus reset - Reallocate channel and bandwidth TODO: if device is detached and reattached, restart transmission if it was started before */ static int _vid21394_busreset_handler( raw1394handle_t raw1394handle, unsigned int generation ) { vid21394handle_t vid21394handle = raw1394_get_userdata( raw1394handle ); int new_node, new_port; raw1394_update_generation( raw1394handle, generation ); // find new port of the device // allows detaching of the device and re-attaching on another port if( !SUCCESS( _vid21394_find_device( vid21394handle->serial_number, &new_node, &new_port ) ) ) { vid21394handle->device_present = 0; return 0; } // find new node of the device if( new_port != vid21394handle->port ) { vid21394handle->device_present = 0; return 0; } /* #ifdef DEBUG */ /* fprintf( stderr, __LIBNAME ": new generation: %d, new node: %d, new port: %d", generation, new_node, new_port ); */ /* #endif */ vid21394handle->port = new_port; vid21394handle->node = new_node; // reallocate channel and bandwidth _1394util_allocate_channel( raw1394handle, vid21394handle->channel ); /* _1394util_allocate_bandwidth( raw1394handle, vid21394handle->bandwidth ); */ return 0; } /* Send a Fcp command to the device Input: vid21394handle fcp_command: quadlet to send as fcp command sync_bit: bit used in fcp_sync_bits Output: response: response code returned by the device to this command Return: STATUS_SUCCESS STATUS_TIMEOUT: command took longer than 1 sec STATUS_FAILURE */ static unicap_status_t _vid21394_send_fcp_command( vid21394handle_t vid21394handle, unsigned long long fcp_command, int sync_bit, unsigned long *response ) { nodeid_t nodeid; raw1394handle_t raw1394handle; unsigned long long prepared_fcp_command; struct timeval cur_time; struct timeval timeout_time; if( !vid21394handle->device_present ) { TRACE( "No device!\n" ); return STATUS_NO_DEVICE; } raw1394handle = vid21394handle->raw1394handle; nodeid = 0xffc0 | vid21394handle->node; sem_init( &vid21394handle->fcp_sync_sem[sync_bit], 0, 0 ); prepared_fcp_command = prepare_fcp_command( fcp_command ); /* TRACE( "prepared fcp command: %016llx\n", prepared_fcp_command ); */ if( 0 > raw1394_write( raw1394handle, nodeid, CSR_REGISTER_BASE + CSR_FCP_COMMAND, sizeof( prepared_fcp_command ), (quadlet_t *)&prepared_fcp_command ) ) { TRACE( "raw1394 write failed\n" ); return STATUS_FAILURE; } if( gettimeofday( &timeout_time, NULL ) < 0 ) { TRACE( "gettimeofday failed\n" ); return STATUS_FAILURE; } timeout_time.tv_sec += FCP_TIMEOUT; // 1 second timeout while( sem_trywait( &vid21394handle->fcp_sync_sem[ sync_bit ] ) != 0 ) { // raw1394_loop_iterate is waked regularly by a seperate thread ( every 500ms ) if( gettimeofday( &cur_time, NULL ) < 0 ) { TRACE( "gettimeofday failed\n" ); return STATUS_FAILURE; } if( ( cur_time.tv_sec > timeout_time.tv_sec ) || ( ( cur_time.tv_sec == timeout_time.tv_sec ) && ( cur_time.tv_usec > timeout_time.tv_usec ) ) ) { TRACE( "timeout\n" ); return STATUS_TIMEOUT; } raw1394_loop_iterate( raw1394handle ); } if( vid21394handle->fcp_status[ sync_bit ] != FCP_ACK_MSG ) { TRACE( "no ack msg\n" ); return STATUS_FAILURE; } if( response ) { *response = vid21394handle->fcp_data; } return STATUS_SUCCESS; } static unicap_status_t _vid21394_send_fcp_command_new( vid21394handle_t vid21394handle, unsigned long long fcp_command, unsigned long sync_bit, void *data, size_t data_length, void *response, size_t *response_length ) { unsigned long prepared_fcp_command[70]; struct timeval cur_time; struct timeval timeout_time; int i; raw1394handle_t raw1394handle = vid21394handle->raw1394handle; nodeid_t nodeid = 0xffc0 | vid21394handle->node; unicap_status_t status = STATUS_SUCCESS; if( data_length > 268 ) { TRACE( "incorrect data length, too much data\n" ); return STATUS_FAILURE; } sem_init( &vid21394handle->fcp_sync_sem[sync_bit], 0, 0 ); prepared_fcp_command[0] = ntohl( FCP_COMMAND ); prepared_fcp_command[1] = ntohl( fcp_command ); for( i = 0; i < data_length; i+=4 ) { prepared_fcp_command[2 + ( i/4 )] = ntohl( *(unsigned long *)(data + i ) ); if( data_length > 4 ) { /* TRACE( "prepare fcpcommand: %d = %08x len: %d\n", 2+(i/4), * (unsigned int )prepared_fcp_command[2 + ( i/4 )], data_length ); */ } } if( 0 > raw1394_write( raw1394handle, nodeid, CSR_REGISTER_BASE + CSR_FCP_COMMAND, (2 * ( sizeof( unsigned long ) ) ) + data_length, (quadlet_t *)prepared_fcp_command ) ) { TRACE( "raw1394 write failed" ); return STATUS_FAILURE; } if( gettimeofday( &timeout_time, NULL ) < 0 ) { return STATUS_FAILURE; } timeout_time.tv_sec += FCP_TIMEOUT; // 10 second timeout while( sem_trywait( &vid21394handle->fcp_sync_sem[sync_bit] ) != 0 ) { // raw1394_loop_iterate is waked regularly by a seperate thread ( every 500ms ) if( gettimeofday( &cur_time, NULL ) < 0 ) { TRACE( "gettimeofday failed\n" ); return STATUS_FAILURE; } if( ( cur_time.tv_sec > timeout_time.tv_sec ) || ( ( cur_time.tv_sec == timeout_time.tv_sec ) && ( cur_time.tv_usec > timeout_time.tv_usec ) ) ) { TRACE( "timeout\n" ); return STATUS_TIMEOUT; } raw1394_loop_iterate( raw1394handle ); } if( vid21394handle->fcp_status[sync_bit] != 0xaa ) { TRACE( "no ack msg\n" ); return STATUS_FAILURE; } if( *response_length <= vid21394handle->fcp_response_length ) { memcpy( response, &vid21394handle->fcp_response[0], vid21394handle->fcp_response_length ); *response_length = vid21394handle->fcp_response_length; } else { status = STATUS_BUFFER_TOO_SMALL; } return status; } /* Send a Fcp command to the device Input: vid21394handle fcp_command: quadlet to send as fcp command sync_bit: bit used in fcp_sync_bits Output: response: response code returned by the device to this command Return: STATUS_SUCCESS STATUS_TIMEOUT: command took longer than 1 sec STATUS_FAILURE */ static unicap_status_t _vid21394_send_fcp_command_ext( vid21394handle_t vid21394handle, unsigned long long fcp_command, unsigned long extra_quad, int sync_bit, unsigned long *response ) { nodeid_t nodeid; raw1394handle_t raw1394handle; unsigned long prepared_fcp_command[3]; struct timeval cur_time; struct timeval timeout_time; if( !vid21394handle->device_present ) { return STATUS_NO_DEVICE; } raw1394handle = vid21394handle->raw1394handle; nodeid = 0xffc0 | vid21394handle->node; vid21394handle->fcp_data = 0; vid21394handle->fcp_ext_data = 0; sem_init( &vid21394handle->fcp_sync_sem[sync_bit], 0, 0 ); prepared_fcp_command[0] = ntohl( FCP_COMMAND ); prepared_fcp_command[1] = ntohl( fcp_command ); prepared_fcp_command[2] = ntohl( extra_quad ); if( 0 > raw1394_write( raw1394handle, nodeid, CSR_REGISTER_BASE + CSR_FCP_COMMAND, 3 * ( sizeof( unsigned long ) ), (quadlet_t *)prepared_fcp_command ) ) { TRACE( "raw1394 write failed\n" ); return STATUS_FAILURE; } if( gettimeofday( &timeout_time, NULL ) < 0 ) { return STATUS_FAILURE; } timeout_time.tv_sec += 1; // 1 second timeout while( sem_trywait( &vid21394handle->fcp_sync_sem[sync_bit] ) != 0 ) { // raw1394_loop_iterate is waked regularly by a seperate thread ( every 500ms ) if( gettimeofday( &cur_time, NULL ) < 0 ) { TRACE( "gettimeofday failed\n" ); return STATUS_FAILURE; } if( ( cur_time.tv_sec > timeout_time.tv_sec ) || ( ( cur_time.tv_sec == timeout_time.tv_sec ) && ( cur_time.tv_usec > timeout_time.tv_usec ) ) ) { TRACE( "timeout command: %08x\n", (unsigned int) fcp_command ); return STATUS_TIMEOUT; } raw1394_loop_iterate( raw1394handle ); } if( vid21394handle->fcp_status[ sync_bit ] != FCP_ACK_MSG ) { TRACE( "no ack msg\n" ); return STATUS_FAILURE; } if( response ) { *response = vid21394handle->fcp_data; } return STATUS_SUCCESS; } /* Find the port the device with the serial number sernum is connected to. Input: raw1394handle sernum Returns: port or -1 if device is unfound */ static int _vid21394_find_device( unsigned long long sernum, int *port, int *node ) { int numcards = 0; struct raw1394_portinfo portinfo[16]; int probeport; int probenode = 0; raw1394handle_t raw1394handle; unicap_status_t status = STATUS_FAILURE; *node = -1; *port = -1; raw1394handle = raw1394_new_handle(); numcards = raw1394_get_port_info( raw1394handle, portinfo, 16 ); if( numcards < 0 ) { TRACE( "Error querying 1394 card info\n" ); return -1; } else if( numcards == 0 ) { TRACE( "No 1394 cards found!\n" ); return -1; } raw1394_destroy_handle( raw1394handle ); for( probeport = 0; ( probeport < numcards ) && ( *node == -1 ); probeport++ ) { if( ( raw1394handle = raw1394_new_handle_on_port( probeport ) ) < 0 ) { TRACE( "Can't set port [%d]\n", probeport ); return -1; } for( probenode = 0; probenode < raw1394_get_nodecount( raw1394handle ); probenode++ ) { unsigned long long guid; guid = get_guid( raw1394handle, probenode ); if( guid == sernum ) { status = STATUS_SUCCESS; *node = probenode; *port = probeport; TRACE( "device found @ port: %d\n", probeport ); break; } else { } } raw1394_destroy_handle( raw1394handle ); } return status; } /* Watchdog thread which wakes raw1394_loop_iterate every 500ms to prevent blocking */ static void *_vid21394_timeout_thread( void *arg ) { timeout_data_t *timeout_data = ( timeout_data_t *) arg; raw1394handle_t raw1394handle = timeout_data->raw1394handle; int i = 0; while( timeout_data->quit == 0 ) { usleep( 5000 ); i++; if( i > 100 ) { raw1394_wake_up( raw1394handle ); i = 0; } } return 0; } /* Returns the firmware version of the converter Input: vid21394handle: handle to the device Output: firmware version or -1 on failure */ int vid21394_get_firm_vers( vid21394handle_t vid21394handle ) { unsigned long long fcp_get_firm_vers = GET_FIRM_VERS_MSG << 24; int bit = GET_FIRM_VERS_MSG - 0x10; int result; result = _vid21394_send_fcp_command( vid21394handle, fcp_get_firm_vers, bit, NULL ); if( SUCCESS( result ) ) { return vid21394handle->firmware_version; } else { return -1; } } /* input: serial number of the device to open, 0 for first free device output: new handle to device, VID21394_INVALID_HANDLE on error error values: EBUSY: requested device already in use by this lib ENODEV: no device with this sernum or no free device ENOMEM: out of memory EAGAIN: raw1394 error, could not get resource ENOSYS: system lacks raw1394 support ENXIO: The requested device was not found on the bus */ vid21394handle_t vid21394_open( unsigned long long sernum )/* raw1394handle_t handle, int node ) */ { raw1394handle_t raw1394handle = NULL; vid21394handle_t vid21394handle = (vid21394handle_t) malloc( sizeof( struct vid21394_handle ) ); if( !vid21394handle ) { return VID21394_INVALID_HANDLE_VALUE; } bzero( vid21394handle, sizeof( struct vid21394_handle ) ); if( sernum ) { int port; int node; if( !SUCCESS(_vid21394_find_device( sernum, &port, &node ) ) ) { raw1394_destroy_handle( raw1394handle ); free( vid21394handle ); return VID21394_INVALID_HANDLE_VALUE; } TRACE( "port: %d node: %d\n", port, node ); raw1394handle = raw1394_new_handle_on_port( port ); if( !raw1394handle ) { if( !errno ) { TRACE( "This kernel lacks raw1394 support!\n" ); free( vid21394handle ); return VID21394_INVALID_HANDLE_VALUE; } else { TRACE( "Could not get raw1394 handle!\n" ); free( vid21394handle ); return VID21394_INVALID_HANDLE_VALUE; } } TRACE( "Open device on port: %d, node: %d\n", port, node ); vid21394handle->port = port; vid21394handle->node = node; } else // !sernum { free( vid21394handle ); return VID21394_INVALID_HANDLE_VALUE; } raw1394_set_userdata( raw1394handle, vid21394handle ); raw1394_set_bus_reset_handler( raw1394handle, _vid21394_busreset_handler ); raw1394_set_fcp_handler( raw1394handle, _vid21394_fcp_handler ); raw1394_start_fcp_listen( raw1394handle ); ucutil_init_queue( &vid21394handle->queued_buffers ); ucutil_init_queue( &vid21394handle->ready_buffers ); vid21394handle->current_data_buffer = 0; vid21394handle->raw1394handle = raw1394handle; vid21394handle->serial_number = sernum; vid21394handle->device_present = 1; vid21394handle->vid21394handle = vid21394handle; vid21394handle->num_buffers = 2; vid21394handle->current_line_offset = 0; vid21394handle->current_line_length = 0; // indicates no video mode set vid21394handle->timeout_data.quit = 0; vid21394handle->timeout_data.raw1394handle = raw1394handle; if( pthread_create( &vid21394handle->timeout_thread, NULL, _vid21394_timeout_thread, &vid21394handle->timeout_data ) ) { TRACE( "Failed to create timeout thread\n" ); } vid21394_get_firm_vers( vid21394handle ); return vid21394handle; } /* Close a device opened by vid21394_open frees bandwidth and channel Input: vid21394handle: handle to the device */ void vid21394_close( vid21394handle_t vid21394handle ) { /* int retval; */ if( !vid21394handle ) { return; } if( vid21394handle->timeout_thread ) { vid21394handle->timeout_data.quit = 1; pthread_join( vid21394handle->timeout_thread, NULL ); vid21394handle->timeout_thread = 0; } if( vid21394handle->bandwidth ) { _1394util_free_bandwidth( vid21394handle->raw1394handle, vid21394handle->bandwidth ); vid21394handle->bandwidth = 0; } if( vid21394handle->channel != -1 ) { _1394util_free_channel( vid21394handle->raw1394handle, vid21394handle->channel ); vid21394handle->channel = -1; } if( vid21394handle->raw1394handle ) { raw1394_destroy_handle( vid21394handle->raw1394handle ); vid21394handle->raw1394handle = 0; } free( vid21394handle ); } /* Start transmission of video data from the converter Input: vid21394handle: handle to the device Output: STATUS_SUCCESS: video mode set successfully STATUS_NO_VIDEO_MODE: no video mode was set prior to this call STATUS_NO_CHANNEL: no isochronous channel free on the 1394 bus STATUS_INSUFFICIENT_BANDWIDTH: not enough free bandwidth on the 1394 bus STATUS_FAILURE: other error */ int vid21394_start_transmit( vid21394handle_t vid21394handle ) { const static unsigned long ENABLE_TRANSMITTER = 0x100; unsigned long long fcp_ena_isoch_tx_command = ENA_ISOCH_TX_MSG << 24; int bit = ENA_ISOCH_TX_MSG - 0x10; int channel, bandwidth; if( !vid21394handle->current_line_length ) { // no video mode set TRACE( "No video mode set!\n" ); return STATUS_NO_VIDEO_MODE; } if( ( channel = _1394util_find_free_channel( vid21394handle->raw1394handle ) ) < 0 ) { TRACE( "Failed to find a free channel!\n" ); return STATUS_NO_CHANNEL; } // calculate bandwidth // bandwidth = 2 * linelength + CIP headers bandwidth = ( vid21394handle->current_line_length * 2 ) + 8; /* if( ( status = _1394util_allocate_bandwidth( raw1394handle, bandwidth ) ) < 0 ) */ /* { */ /* _1394util_free_channel( raw1394handle, channel ); */ /* return status; */ /* } */ vid21394handle->channel = channel; /* vid21394handle->bandwidth = bandwidth; */ fcp_ena_isoch_tx_command = fcp_ena_isoch_tx_command | ENABLE_TRANSMITTER ; fcp_ena_isoch_tx_command = fcp_ena_isoch_tx_command | ( channel << 16 ); /* fcp_ena_isoch_tx_command = prepare_fcp_command( fcp_ena_isoch_tx_command ); */ TRACE( "vid21394: transmitting on channel: %d %016llx\n", channel, fcp_ena_isoch_tx_command ); return( _vid21394_send_fcp_command( vid21394handle, fcp_ena_isoch_tx_command, bit, NULL ) ); } /* Stop transmission of video data from the converter Input: vid21394handle: handle to the device Return: status */ int vid21394_stop_transmit( vid21394handle_t vid21394handle ) { const static unsigned long DISABLE_TRANSMITTER = 0x000; unsigned long long fcp_ena_isoch_tx_command = ENA_ISOCH_TX_MSG << 24; int bit = ENA_ISOCH_TX_MSG - 0x10; unsigned long channel = 0; TRACE( "verify me: stop channel\n" ); fcp_ena_isoch_tx_command = fcp_ena_isoch_tx_command | DISABLE_TRANSMITTER ; fcp_ena_isoch_tx_command = fcp_ena_isoch_tx_command | ( channel << 16 ); return( _vid21394_send_fcp_command( vid21394handle, fcp_ena_isoch_tx_command, bit, NULL ) ); } /* Set input channel Input: vid21394handle: handle to the device channel: new input channel Returns: STATUS_SUCCESS STATUS_TIMEOUT STATUS_NO_DEVICE STATUS_FAILURE */ int vid21394_set_input_channel( vid21394handle_t vid21394handle, enum vid21394_input_channel channel ) { unsigned long long fcp_input_select = INPUT_SELECT_MSG << 24; int bit = INPUT_SELECT_MSG - 0x10; fcp_input_select = fcp_input_select | ( channel << 16 ); TRACE( "set input channel: %d\n", channel ); return( _vid21394_send_fcp_command( vid21394handle, fcp_input_select, bit, NULL ) ); } unicap_status_t vid21394_get_input_channel( vid21394handle_t vid21394handle, enum vid21394_input_channel *channel ) { unsigned long long fcp = CHK_VIDEO_LOCK_MSG << 24; int bit = CHK_VIDEO_LOCK_MSG - 0x10; unsigned long response; unicap_status_t status; status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); response = ( response >> 8 ) & 0xff; *channel = response; return status; } /* Set brightness level Input: vid21394handle brightness Returns: STATUS_SUCCESS STATUS_TIMEOUT STATUS_NO_DEVICE STATUS_FAILURE STATUS_INVALID_PARAMETER: brightness level not in valid range */ unicap_status_t vid21394_set_brightness( vid21394handle_t vid21394handle, unsigned int brightness ) { unsigned long long fcp_write_i2c = WRITE_I2C_BYTE_MSG << 24; int bit = WRITE_I2C_BYTE_MSG - 0x10; fcp_write_i2c |= I2C_SAA7112_ID; fcp_write_i2c |= I2C_BRIGHTNESS; fcp_write_i2c |= brightness & 0xff; return( _vid21394_send_fcp_command( vid21394handle, fcp_write_i2c, bit, NULL ) ); } unicap_status_t vid21394_get_brightness( vid21394handle_t vid21394handle, unsigned int *brightness ) { unsigned long long fcp = READ_I2C_BYTE_MSG << 24; int bit = READ_I2C_BYTE_MSG - 0x10; unicap_status_t status; unsigned long response; fcp |= I2C_SAA7112_ID | I2C_BRIGHTNESS; status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); *brightness = response & 0xff; return status; } /* Set video standard ( PAL = 50 Hz, NTSC = 60 Hz ) Input: vid21394handle freq: VID21394_FREQ_50, VID21394_FREQ_60, VID21394_FREQ_AUTO Returns: STATUS_SUCCESS STATUS_TIMEOUT STATUS_NO_DEVICE STATUS_FAILURE STATUS_INVALID_PARAMETER */ unicap_status_t vid21394_set_frequency( vid21394handle_t vid21394handle, enum vid21394_frequency freq ) { unsigned long long fcp_write_freq = SET_VIDEO_FREQUENCY_MSG << 24; int bit = SET_VIDEO_FREQUENCY_MSG - 0x10; fcp_write_freq |= freq <<16; return( _vid21394_send_fcp_command( vid21394handle, fcp_write_freq, bit, NULL ) ); } unicap_status_t vid21394_get_frequency( vid21394handle_t vid21394handle, enum vid21394_frequency *freq ) { unsigned long long fcp = CHK_VIDEO_LOCK_MSG << 24; int bit = CHK_VIDEO_LOCK_MSG - 0x10; unsigned long response; unicap_status_t status; status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); if( response & 2 ) { *freq = VID21394_FREQ_60; } else { *freq = VID21394_FREQ_50; } return status; } /* Set byte order See Table 88, page 103 */ unicap_status_t vid21394_set_byte_order( vid21394handle_t vid21394handle, vid21394_byte_order_t order ) { unsigned long long fcp_write_i2c = WRITE_I2C_BYTE_MSG << 24; int bit = WRITE_I2C_BYTE_MSG - 0x10; fcp_write_i2c |= I2C_SAA7112_ID; fcp_write_i2c |= I2C_BYTE_ORDER; fcp_write_i2c |= ( order << 6 ) & 0xff; return( _vid21394_send_fcp_command( vid21394handle, fcp_write_i2c, bit, NULL ) ); } /* Set contrast level Input: vid21394handle contrast Returns: STATUS_SUCCESS STATUS_TIMEOUT STATUS_NO_DEVICE STATUS_FAILURE STATUS_INVALID_PARAMETER: contrast level not in valid range */ unicap_status_t vid21394_set_contrast( vid21394handle_t vid21394handle, unsigned int contrast ) { unsigned long long fcp_write_i2c = WRITE_I2C_BYTE_MSG << 24; int bit = WRITE_I2C_BYTE_MSG - 0x10; fcp_write_i2c |= I2C_SAA7112_ID; fcp_write_i2c |= I2C_CONTRAST; fcp_write_i2c |= contrast & 0xff; return( _vid21394_send_fcp_command( vid21394handle, fcp_write_i2c, bit, NULL ) ); } /* Get contrast level Output: contrast : Current contrast level */ unicap_status_t vid21394_get_contrast( vid21394handle_t vid21394handle, unsigned int *contrast ) { unsigned long long fcp = READ_I2C_BYTE_MSG << 24; int bit = READ_I2C_BYTE_MSG - 0x10; unicap_status_t status; unsigned long response; fcp |= I2C_SAA7112_ID | I2C_CONTRAST; status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); *contrast = response & 0xff; return status; } /* Force the device to tag fields as odd/even even if the input only provides one field type Input: force : 1 to enable; 0 to disable */ unicap_status_t vid21394_set_force_odd_even( vid21394handle_t vid21394handle, unsigned int force ) { unsigned long long fcp_write_i2c = READ_I2C_BYTE_MSG << 24; int bit = READ_I2C_BYTE_MSG - 0x10; unsigned long response; force = force?1:0; fcp_write_i2c |= I2C_SAA7112_ID; fcp_write_i2c |= I2C_SYNCCONTROL; _vid21394_send_fcp_command( vid21394handle, fcp_write_i2c, bit, &response ); response &= ~(1<<5); response |= force<<5; bit = WRITE_I2C_BYTE_MSG - 0x10; fcp_write_i2c = WRITE_I2C_BYTE_MSG << 24; fcp_write_i2c |= I2C_SAA7112_ID; fcp_write_i2c |= I2C_SYNCCONTROL; fcp_write_i2c |= response & 0xff; return( _vid21394_send_fcp_command( vid21394handle, fcp_write_i2c, bit, NULL ) ); } /* Get current state of odd/even flag */ unicap_status_t vid21394_get_force_odd_even( vid21394handle_t vid21394handle, unsigned int *force ) { unsigned long long fcp = READ_I2C_BYTE_MSG << 24; int bit = READ_I2C_BYTE_MSG - 0x10; unsigned long response; unicap_status_t status; fcp |= I2C_SAA7112_ID; fcp |= I2C_SYNCCONTROL; status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); *force = (response>>5)&1; return status; } unicap_status_t vid21394_force_s200( vid21394handle_t vid21394handle ) { unsigned long long fcp = READ_LINK_REG_MSG << 24; int bit = READ_LINK_REG_MSG - 0x10; unsigned long response; unicap_status_t status; fcp |= 0x34 << 8; // ITXCTL register base address status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); /* printf( "link reg1: %08x\n", response ); */ fcp = WRITE_LINK_REG_MSG << 24; fcp |= 0x34 << 8; // ITXCTL register base address response &= ~0xf0; // Mask out SPD response |= 1<<4; // 0 == S100 , 1 == S200 , 2 == S400 _vid21394_send_fcp_command_ext( vid21394handle, fcp, response, bit, NULL ); fcp = READ_LINK_REG_MSG << 24; fcp |= 0x34 << 8; // ITXCTL register base address status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); /* printf( "link reg2: %08x\n", response ); */ return status; } #if VID21394_BOOTLOAD unicap_status_t vid21394_enter_bootload( vid21394handle_t vid21394handle ) { unsigned long long fcp = ENTER_BOOTLOAD_MSG << 24; int bit = READ_LINK_REG_MSG - 0x10; unsigned long response; unicap_status_t status; TRACE( "enter bootload\n" ); status = _vid21394_send_fcp_command( vid21394handle, fcp, bit, &response ); return status; } #endif unicap_status_t vid21394_rs232_io( vid21394handle_t vid21394handle, unsigned char *out_data, int out_data_length, unsigned char *in_data, int in_data_length ) { unsigned long long fcp = RS232_IO_MSG << 24; int bit = RS232_IO_MSG - 0x10; fcp |= out_data_length << 8; fcp |= in_data_length; /* TRACE( "rs232io fcp: %08llx out_data_length: %d, in_data_length: %d\n", fcp, out_data_length, in_data_length ); */ return( _vid21394_send_fcp_command_new( vid21394handle, fcp, bit, out_data, out_data_length, in_data, (unsigned int *)&in_data_length ) ); } unicap_status_t vid21394_read_rs232( vid21394handle_t vid21394handle, unsigned char *data, int *datalen ) { unsigned long long fcp = RS232_IO_MSG << 24; int bit = RS232_IO_MSG - 0x10; int offset = 0; unsigned long poll_len = 1; while( poll_len && ( *datalen > (offset + 4) ) ) { int i; fcp = RS232_IO_MSG << 24; if( !SUCCESS( _vid21394_send_fcp_command_ext( vid21394handle, fcp, 0, bit, &poll_len ) ) ) { TRACE( "failed\n" ); return STATUS_FAILURE; } usleep( 100 ); if( poll_len ) { /* TRACE( "offset: %d *datalen: %d poll_len: %d\n", offset, *datalen, poll_len ); */ if( poll_len > 4 ) { /* TRACE( "len > 4!!!!\n\n\n\n\n\n\n\n\n\n\n\n" ); */ return STATUS_FAILURE; } for( i = 0; i < poll_len; i++ ) { *(data+offset+i) = vid21394handle->fcp_ext_data & 0xff; vid21394handle->fcp_ext_data = vid21394handle->fcp_ext_data>>8; } offset += poll_len; } } *datalen = offset; return STATUS_SUCCESS; } unicap_status_t vid21394_rs232_set_baudrate( vid21394handle_t vid21394handle, int rate ) { unsigned long long fcp = RS232_CONFIG_MSG << 24; int bit = RS232_CONFIG_MSG - 0x10; unsigned long fcp_data = 0; fcp |= 1<<8; TRACE( "SET BAUD RATE\n" ); switch( rate ) { case 2400: fcp_data = 1<<24; break; case 4800: fcp_data = 2<<24; break; case 9600: fcp_data = 3<<24; break; case 19200: fcp_data = 4<<24; break; case 38400: fcp_data = 5<<24; break; } return( _vid21394_send_fcp_command_ext( vid21394handle, fcp, fcp_data, bit, NULL ) ); } unicap_status_t vid21394_set_link_speed( vid21394handle_t vid21394handle, int speed ) { unsigned long long fcp = LINK_SPEED_MSG << 24; int bit = LINK_SPEED_MSG - 0x10; fcp |= 1<<8; TRACE( "SET SPEED\n" ); fcp |= speed; return( _vid21394_send_fcp_command( vid21394handle, fcp, bit, NULL ) ); } /* Set video mode Input: vid21394handle video_mode: VID21394_Y_320x240 VID21394_Y41P_320x240 VID21394_UYVY_320x240 VID21394_Y_640x480 VID21394_Y41P_640x480 VID21394_UYVY_640x480 VID21394_Y_768x576 VID21394_Y41P_768x576 VID21394_UYVY_768x576 Returns: STATUS_SUCCESS STATUS_TIMEOUT STATUS_NO_DEVICE STATUS_FAILURE STATUS_INVALID_PARAMETER: unknown mode */ unicap_status_t vid21394_set_video_mode( vid21394handle_t vid21394handle, enum vid21394_video_mode video_mode ) { unsigned long long fcp_set_video_mode = SET_VIDEO_MODE_MSG << 24; int status = STATUS_FAILURE; int bit = SET_VIDEO_MODE_MSG - 0x10; int result; fcp_set_video_mode = fcp_set_video_mode | ( ( video_mode & 0xff ) <<16); result = _vid21394_send_fcp_command( vid21394handle, fcp_set_video_mode, bit, NULL ); if( !SUCCESS( result ) ) { TRACE( "set_video mode failed!\n" ); return result; } if( video_mode & 0xff00 ) { vid21394_set_byte_order( vid21394handle, VID21394_BYTE_ORDER_YUYV ); } else { vid21394_set_byte_order( vid21394handle, VID21394_BYTE_ORDER_UYVY ); } vid21394handle->current_offset = 0; vid21394handle->current_field = 0; vid21394handle->current_line_offset = 0; vid21394handle->current_line_length = vid21394_video_mode_line_lengths[ video_mode & 0xff ]; vid21394handle->current_buffer_size = vid21394_video_mode_sizes[ video_mode & 0xff ]; vid21394handle->current_line_to_copy = vid21394handle->current_line_length; vid21394handle->current_bytes_copied = 0; vid21394handle->copy_done = 0; vid21394handle->start_copy = 0; TRACE( "set video_mode: %d\n", video_mode ); vid21394handle->video_mode = video_mode; status = STATUS_SUCCESS; return status; } /* Queue a buffer to get filled by the device. Queued buffers should not be touched until returned by vid21394_wait_buffer() ( especially they must not be freed ). Queued buffers can be dequeued one after the other with vid21394_dequeue_buffer() ( reception needs to be stopped first ) Input: vid21394handle buffer: buffer for the image, needs to be large enough to store complete frame */ void vid21394_queue_buffer( vid21394handle_t vid21394handle, void * buffer ) { struct _unicap_queue *entry; entry = malloc( sizeof( struct _unicap_queue ) ); entry->data = buffer; ucutil_insert_back_queue( &vid21394handle->queued_buffers, entry ); } /* Removes the first buffer from the queue. Can only be called if reception is stopped! Once queued with vid21394_queue_buffer, only free buffers returned by vid21394_dequeue_buffer() or vid2134_wait_buffer()! Input: vid21394handle Returns: pointer to the buffer or NULL if no buffer was dequeued */ void *vid21394_dequeue_buffer( vid21394handle_t vid21394handle ) { void *retval; if( vid21394handle->is_receiving ) { // device has to be stopped first return NULL; } retval = ucutil_get_front_queue( &vid21394handle->queued_buffers )->data; return retval; } /* Wait until one buffer got filled by the device. May return immediately ( if a buffer already was filled by the device ) or block until the buffer got filled. */ int vid21394_wait_buffer( vid21394handle_t vid21394handle, void **buffer ) { int retval = STATUS_SUCCESS; if( !vid21394handle->ready_buffers.next && !vid21394handle->is_receiving ) { return STATUS_IS_STOPPED; } if( !vid21394handle->ready_buffers.next && !vid21394handle->device_present ) { return STATUS_NO_DEVICE; } if( vid21394handle->ready_buffers.next ) { unicap_queue_t *first_entry; // return immediately if a buffer is already in the ready queue first_entry = ucutil_get_front_queue( &vid21394handle->ready_buffers ); *buffer = first_entry->data; free( first_entry ); } else { if( vid21394handle->queued_buffers.next ) { //block until a buffer got filled by the device unicap_queue_t *first_entry; struct timeval timeout_time, cur_time; if( gettimeofday( &timeout_time, NULL ) < 0 ) { return STATUS_FAILURE; } timeout_time.tv_sec += 1; // 1 second timeout while( !vid21394handle->ready_buffers.next ) { // raw1394_loop_iterate is waked regularly by a seperate thread ( every 500ms ) if( gettimeofday( &cur_time, NULL ) < 0 ) { return STATUS_FAILURE; } if( timercmp( &cur_time, &timeout_time, > ) ) { return STATUS_TIMEOUT; } /* // dcm: don't enter into loop_iterate since, it can block even if a frame arrives raw1394_loop_iterate( vid21394handle->raw1394handle ); */ // 1 millisecond struct timespec delay = {0, 1000000}; nanosleep(&delay, NULL); } first_entry = ucutil_get_front_queue( &vid21394handle->ready_buffers ); *buffer = first_entry->data; free( first_entry ); } else { // no buffers queued -> no buffers to return return STATUS_NO_BUFFERS; } } return retval; } /* returns the number of completed buffers */ int vid21394_poll_buffer( vid21394handle_t vid21394handle ) { int buffers = 0; /* unicap_queue_t *entry = &vid21394handle->ready_buffers; */ /* while( entry->next ) */ /* { */ /* buffers++; */ /* entry = entry->next; */ /* } */ return ucutil_queue_get_size( &vid21394handle->ready_buffers ); } void _vid21394_add_to_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { ucutil_insert_back_queue( queue, entry ); } #define START_COPY_ON_NEXT_SY 0 #define CONTINUE_COPY_DURING_SY 1 #define COPY_NOSY 2 #define SKIP_TO_NEXT_SY 3 /* Iso callback Weaves one odd and one even field into a frame */ enum raw1394_iso_disposition _vid21394_new_iso_handler( raw1394handle_t handle, unsigned char *data, unsigned int length, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped ) { vid21394handle_t vid21394handle = raw1394_get_userdata( handle ); unsigned int field_type; int remaining_length; #ifdef DEBUG static unsigned int last_cycle = -1; if( last_cycle != -1 && ( ( ( last_cycle + 1 ) % 8000 ) != cycle ) ) { TRACE( "packet discontinuity: %u, last:%u\n", cycle, last_cycle ); last_cycle = cycle; } vid21394handle->nr_pkts += 1; #endif /* bail out on empty or bogus/corrupt packets */ if( ( length <= 8 ) || ( length >4096 ) ) { #ifdef DEBUG if( length > 4096 ) { TRACE( "invalid length in iso callback!\n" ); } #endif return 0; } /* Check for bogus values */ if( ( ( sy != 0 ) && ( sy != 1 ) && ( sy != 4 ) ) || ( channel != vid21394handle->channel ) || ( !data ) ) { TRACE( "corrupt packet in iso callback!\n" ); return 0; } if( ( vid21394handle->firmware_version & 0xff00 ) < 0x200 ) { field_type = vid21394handle->last_field_type == 0 ? 0:1; } else { field_type = *(data+7) == 4 ? 0:1; } if( sy == 1 ) { switch( vid21394handle->start_copy ) { case COPY_NOSY: { // SY field is set while we where still waiting for data to finish a field // => Not enough data transmitted vid21394handle->start_copy = 0; vid21394handle->nr_pkts = 0; //start over with this field } /* break; */ case START_COPY_ON_NEXT_SY: { // A new field starts here if( !vid21394handle->current_data_buffer ) { if( vid21394handle->current_format.buffer_type == UNICAP_BUFFER_TYPE_USER ) { vid21394handle->current_data_buffer = ucutil_get_front_queue( &vid21394handle->queued_buffers ); if( !vid21394handle->current_data_buffer ) { TRACE( "No buffer!\n" ); vid21394handle->start_copy = SKIP_TO_NEXT_SY; return 0; } } else { vid21394handle->current_data_buffer = & vid21394handle->system_buffer_entry; } } #ifdef DEBUG vid21394handle->nr_pkts = 0; #endif vid21394handle->current_offset = 0; vid21394handle->current_line_to_copy = vid21394handle->current_line_length; vid21394handle->current_offset += field_type * vid21394handle->current_line_length; vid21394handle->start_copy = 1; } break; case SKIP_TO_NEXT_SY: { return 0; } break; case CONTINUE_COPY_DURING_SY: { } break; default: { /* TRACE( "Unknown state while synching to the next field!\n" ); */ return 0; } break; } } else { vid21394handle->last_field_type = sy; if( vid21394handle->start_copy == START_COPY_ON_NEXT_SY ) { return 0; } else if( vid21394handle->start_copy == SKIP_TO_NEXT_SY ) { vid21394handle->start_copy = START_COPY_ON_NEXT_SY; return 0; } else { vid21394handle->start_copy = COPY_NOSY; } } remaining_length = ( length - 8 ); // This copy routine weaves two fields into a frame if( ( vid21394handle->current_bytes_copied + remaining_length ) <= (vid21394handle->current_buffer_size/2) ) { int tmplen = 0; int tmpoffset = 0; while( remaining_length ) { if( remaining_length >= vid21394handle->current_line_to_copy ) { tmplen = vid21394handle->current_line_to_copy; } else { tmplen = remaining_length; } memcpy( ((char*)vid21394handle->current_data_buffer->data) + vid21394handle->current_offset, (data+8) + tmpoffset, tmplen ); vid21394handle->current_offset += tmplen; tmpoffset += tmplen; remaining_length -= tmplen; vid21394handle->current_bytes_copied += tmplen; vid21394handle->current_line_to_copy -= tmplen; if( vid21394handle->current_line_to_copy <= 0 ) { vid21394handle->current_line_to_copy = vid21394handle->current_line_length; vid21394handle->current_offset += vid21394handle->current_line_length; // skip one line } } if( vid21394handle->current_bytes_copied == (vid21394handle->current_buffer_size/2) ) { // complete field got copied if( field_type == 0 ) { vid21394handle->copied_field_0 = 1; } else { vid21394handle->copied_field_1 = 1; } if( ( vid21394handle->copied_field_0 ) && ( vid21394handle->copied_field_1 ) ) { // complete frame ( 2 fields ) got copied unicap_data_buffer_t data_buffer; unicap_copy_format( &data_buffer.format, &vid21394handle->current_format ); data_buffer.buffer_size = data_buffer.format.buffer_size; data_buffer.data = vid21394handle->current_data_buffer->data; gettimeofday( &data_buffer.fill_time, NULL ); if( field_type != 0 ){ data_buffer.flags = UNICAP_FLAGS_BUFFER_TYPE_SYSTEM | UNICAP_FLAGS_BUFFER_INTERLACED | UNICAP_FLAGS_BUFFER_ODD_FIELD_FIRST; unicap_data_buffer_t *b; b = ( unicap_data_buffer_t * )vid21394handle->current_data_buffer->data; if( b ) b->flags |= UNICAP_FLAGS_BUFFER_INTERLACED | UNICAP_FLAGS_BUFFER_ODD_FIELD_FIRST; } else { data_buffer.flags = UNICAP_FLAGS_BUFFER_TYPE_SYSTEM | UNICAP_FLAGS_BUFFER_INTERLACED; unicap_data_buffer_t *b; b = ( unicap_data_buffer_t * )vid21394handle->current_data_buffer->data; if( b ){ b->flags |= UNICAP_FLAGS_BUFFER_INTERLACED; b->flags &= ~UNICAP_FLAGS_BUFFER_ODD_FIELD_FIRST; } } vid21394handle->event_callback( vid21394handle->unicap_handle, UNICAP_EVENT_NEW_FRAME, &data_buffer ); if( vid21394handle->current_format.buffer_type == UNICAP_BUFFER_TYPE_USER ) { ucutil_insert_back_queue( &vid21394handle->ready_buffers, vid21394handle->current_data_buffer ); } vid21394handle->current_data_buffer = 0; vid21394handle->copied_field_0 = vid21394handle->copied_field_1 = 0; } vid21394handle->start_copy = 0; vid21394handle->current_bytes_copied = 0; } else if( vid21394handle->current_bytes_copied > vid21394handle->current_buffer_size/2 ) { /* TRACE( "Tried to copy too much data: %d\n", vid21394handle->current_offset ); */ } } else { /* TRACE( "Out of bounds\n" ); */ vid21394handle->start_copy = START_COPY_ON_NEXT_SY; vid21394handle->copied_field_0 = vid21394handle->copied_field_1 = 0; vid21394handle->current_bytes_copied = 0; } return 0; } void * vid21394_capture_thread( vid21394handle_t vid21394handle ) { raw1394handle_t raw1394handle = raw1394_new_handle_on_port( vid21394handle->port ); unicap_status_t status = STATUS_SUCCESS; pthread_t wakeup_thread; timeout_data_t timeout_data; if( 0 > raw1394_iso_recv_init( raw1394handle, _vid21394_new_iso_handler, 2000, 3100, vid21394handle->channel, #if RAW1394_1_1_API RAW1394_DMA_PACKET_PER_BUFFER, #endif 100 ) ) { TRACE( "iso_recv_init failed: %s\n", strerror(errno) ); raw1394_destroy_handle( raw1394handle ); return NULL; } if( 0 > raw1394_iso_recv_start( raw1394handle, -1, -1, 0 ) ) { TRACE( "iso_recv_start failed\n" ); raw1394_destroy_handle( raw1394handle ); return NULL; } vid21394handle->is_receiving = SUCCESS( status ); timeout_data.raw1394handle = raw1394handle; timeout_data.quit = 0; if( pthread_create( &wakeup_thread, NULL, (void*(*)(void*))_vid21394_timeout_thread, (void*)&timeout_data ) ) { perror( "create wakeup thread\n" ); } raw1394_set_userdata( raw1394handle, vid21394handle ); while( !vid21394handle->stop_capture ) { raw1394_loop_iterate( raw1394handle ); } timeout_data.quit = 1; pthread_join( wakeup_thread, NULL ); vid21394handle->is_receiving = 0; raw1394_iso_stop( raw1394handle ); raw1394_iso_shutdown( raw1394handle ); if( vid21394handle->bandwidth ) { _1394util_free_bandwidth( raw1394handle, vid21394handle->bandwidth ); vid21394handle->bandwidth = 0; } if( vid21394handle->channel ) { _1394util_free_channel( raw1394handle, vid21394handle->channel ); vid21394handle->channel = -1; } raw1394_destroy_handle( raw1394handle ); return NULL; } /* vid21394_start_receive start reception of the isochronous stream channel has to be allocated and set in the handle */ int vid21394_start_receive( vid21394handle_t vid21394handle ) { raw1394handle_t raw1394handle = vid21394handle->raw1394handle; unicap_status_t status = STATUS_SUCCESS; TRACE( "recv init channel: %d\n", vid21394handle->channel ); vid21394handle->timeout_data.capture_running = 1; if( 0 > raw1394_iso_recv_init( raw1394handle, _vid21394_new_iso_handler, 2000, 3100, vid21394handle->channel, #if RAW1394_1_1_API RAW1394_DMA_PACKET_PER_BUFFER, #endif 100 ) ) { TRACE( "iso_recv_init failed: %s\n", strerror(errno) ); return STATUS_FAILURE; } if( 0 > raw1394_iso_recv_start( raw1394handle, -1, -1, -1 ) ) { TRACE( "iso_recv_start failed\n" ); return STATUS_FAILURE; } vid21394handle->is_receiving = SUCCESS( status ); return status; } /* stops reception of isochronous data, frees allocated bandwidth and channel */ int vid21394_stop_receive( vid21394handle_t vid21394handle ) { vid21394handle->is_receiving = 0; vid21394handle->timeout_data.capture_running = 0; raw1394_iso_stop( vid21394handle->raw1394handle ); raw1394_iso_shutdown( vid21394handle->raw1394handle ); if( vid21394handle->bandwidth ) { _1394util_free_bandwidth( vid21394handle->raw1394handle, vid21394handle->bandwidth ); vid21394handle->bandwidth = 0; } if( vid21394handle->channel ) { _1394util_free_channel( vid21394handle->raw1394handle, vid21394handle->channel ); vid21394handle->channel = -1; } return STATUS_SUCCESS; } libunicap/cpi/vid21394/visca.c0000644000175000017500000004356313164711411016501 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari ( arne_caspari@users.sourceforge.net ) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include "unicap.h" #include "vid21394_base.h" #include "visca.h" #include "visca_private.h" #include "visca_property_table.h" #if VID21394_DEBUG #define DEBUG #endif #include "debug.h" // -------------------------------------------------------------------------- // Constants and Definitions // -------------------------------------------------------------------------- struct ae_mode { char param; char *menu_item; }; struct ae_mode ae_modes[] = { { VISCA_AE_MODE_FULL_AUTO, VISCA_AE_MENU_ITEM_FULL_AUTO }, { VISCA_AE_MODE_MANUAL, VISCA_AE_MENU_ITEM_MANUAL }, { VISCA_AE_MODE_SHUTTER_PRIO, VISCA_AE_MENU_ITEM_SHUTTER_PRIO }, { VISCA_AE_MODE_IRIS_PRIO, VISCA_AE_MENU_ITEM_IRIS_PRIO }, { VISCA_AE_MODE_BRIGHT, VISCA_AE_MENU_ITEM_BRIGHT }, { 0xff, 0 } }; // -------------------------------------------------------------------------- // Helper functions // -------------------------------------------------------------------------- static void visca_init_command_packet_1( unsigned char *packet_data, unsigned char command, unsigned char param1 ) { packet_data[0] = 0x81; packet_data[1] = 0x01; packet_data[2] = 0x04; packet_data[3] = command; packet_data[4] = param1; packet_data[5] = 0xff; } static void visca_init_command_packet_4( unsigned char *packet_data, unsigned char command, unsigned char param1, unsigned char param2, unsigned char param3, unsigned char param4 ) { packet_data[0] = 0x81; packet_data[1] = 0x01; packet_data[2] = 0x04; packet_data[3] = command; packet_data[4] = param1; packet_data[5] = param2; packet_data[6] = param3; packet_data[7] = param4; packet_data[8] = 0xff; } static void visca_init_inq_packet( unsigned char *packet_data, unsigned char command ) { packet_data[0] = 0x81; packet_data[1] = 0x09; packet_data[2] = 0x04; packet_data[3] = command; packet_data[4] = 0xff; } static void visca_init_device_type_inq_packet( unsigned char *packet_data ) { packet_data[0] = 0x81; packet_data[1] = 0x09; packet_data[2] = 0x00; packet_data[3] = 0x02; packet_data[4] = 0xff; } static void visca_htofla( unsigned char *ar, size_t s ) { unsigned int *i_ar; int i; i_ar = ( unsigned int *)ar; if( s % 4 ) { s += 4 - ( s%4 ); } for( i = 0; i < ( s/4 ); i++ ) { i_ar[i] = htonl( i_ar[i] ); } } // -------------------------------------------------------------------------- // Functions // -------------------------------------------------------------------------- unicap_status_t visca_check_inq_response( unsigned char *response ) { unicap_status_t status = STATUS_SUCCESS; if( ( response[1] & 0xf0 ) != VISCA_COMMAND_COMPLETE ) { status = STATUS_FAILURE; } return status; } unicap_status_t visca_set_white_balance( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 6; in_bytes = 6; if( property->flags & UNICAP_FLAGS_AUTO ) { visca_init_command_packet_1( out_data, VISCA_COMMAND_WHITE_BALANCE, VISCA_WHITE_BALANCE_AUTO ); } else { if( property->value == 3200 ) { visca_init_command_packet_1( out_data, VISCA_COMMAND_WHITE_BALANCE, VISCA_WHITE_BALANCE_INDOOR ); } else { visca_init_command_packet_1( out_data, VISCA_COMMAND_WHITE_BALANCE, VISCA_WHITE_BALANCE_OUTDOOR ); } } visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_white_balance( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 4; visca_init_inq_packet( out_data, VISCA_COMMAND_WHITE_BALANCE ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { status = visca_check_inq_response( in_data ); property->flags = UNICAP_FLAGS_MANUAL; switch( in_data[2] ) { case VISCA_WHITE_BALANCE_AUTO: { property->flags = UNICAP_FLAGS_AUTO; } break; case VISCA_WHITE_BALANCE_INDOOR: { property->value = 3200; } break; case VISCA_WHITE_BALANCE_OUTDOOR: { property->value = 5600; } break; } } return status; } unicap_status_t visca_set_zoom( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[12]; unsigned char in_data[8]; unicap_status_t status; unsigned char p1, p2, p3, p4; unsigned int value; out_bytes = 9; in_bytes = 3; value = property->value; p1 = ( value >> 12 ) & 0xf; p2 = ( value >> 8 ) & 0xf; p3 = ( value >> 4 ) & 0xf ; p4 = value & 0xf; visca_init_command_packet_4( out_data, VISCA_COMMAND_ZOOM_DIRECT, p1, p2, p3, p4 ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_zoom( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 7; visca_init_inq_packet( out_data, VISCA_COMMAND_ZOOM_DIRECT ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { property->value = ( in_data[2] * 0x1000 + in_data[3] * 0x100 + in_data[4] * 0x10 + in_data[5] ); } return status; } unicap_status_t visca_set_focus( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[12]; unsigned char in_data[8]; unicap_status_t status; if( property->flags & UNICAP_FLAGS_AUTO ) { out_bytes = 6; in_bytes = 6; visca_init_command_packet_1( out_data, VISCA_COMMAND_FOCUS_AUTO, VISCA_FOCUS_AUTO ); } else { out_bytes = 6; in_bytes = 6; visca_init_command_packet_1( out_data, VISCA_COMMAND_FOCUS_AUTO, VISCA_FOCUS_MANUAL ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { unsigned char p1, p2, p3, p4; unsigned int value; out_bytes = 9; in_bytes = 6; value = property->value; p1 = ( value >> 12 ) & 0xf; p2 = ( value >> 8 ) & 0xf; p3 = ( value >>4 ) & 0xf; p4 = value & 0xf; visca_init_command_packet_4( out_data, VISCA_COMMAND_FOCUS_DIRECT, p1, p2, p3, p4 ); } else { return status; } } visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_focus( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 4; visca_init_inq_packet( out_data, VISCA_COMMAND_FOCUS_AUTO ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { status = visca_check_inq_response( in_data ); property->flags = UNICAP_FLAGS_MANUAL; switch( in_data[2] ) { case VISCA_FOCUS_AUTO: { property->flags = UNICAP_FLAGS_AUTO; /* TRACE( "AUTO FOCUS enabled\n" ); */ } break; default: case VISCA_FOCUS_MANUAL: { /* TRACE( "MANUAL FOCUS enabled\n" ); */ } break; } out_bytes = 5; in_bytes = 7; visca_init_inq_packet( out_data, VISCA_COMMAND_FOCUS_DIRECT ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { property->value = ( in_data[2] * 0x1000 + in_data[3] * 0x100 + in_data[4] * 0x10 + in_data[5] ); } } return status; } unicap_status_t visca_set_gain( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[12]; unsigned char in_data[8]; unicap_status_t status; unsigned char p3, p4; unsigned int value = property->value; out_bytes = 9; in_bytes = 6; p3 = ( value & 0xf0 ) >> 8; p4 = value & 0xf; visca_init_command_packet_4( out_data, VISCA_COMMAND_FOCUS_DIRECT, 0, 0, p3, p4 ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_gain( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 7; visca_init_inq_packet( out_data, VISCA_COMMAND_GAIN_DIRECT ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { property->value = ( in_data[4] * 0x10 + in_data[5] ); } property->flags = UNICAP_FLAGS_MANUAL; return status; } unicap_status_t visca_set_shutter( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[12]; unsigned char in_data[8]; unicap_status_t status; unsigned char p3, p4; unsigned int value = property->value; out_bytes = 9; in_bytes = 6; p3 = ( value & 0xf0 ) >> 8; p4 = value & 0xf; visca_init_command_packet_4( out_data, VISCA_COMMAND_SHUTTER_DIRECT, 0, 0, p3, p4 ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_shutter( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 7; visca_init_inq_packet( out_data, VISCA_COMMAND_SHUTTER_DIRECT ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { property->value = ( in_data[4] * 0x10 + in_data[5] ); } property->flags = UNICAP_FLAGS_MANUAL; return status; } unicap_status_t visca_set_iris( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[12]; unsigned char in_data[8]; unicap_status_t status; unsigned char p3, p4; unsigned int value = property->value; out_bytes = 9; in_bytes = 6; p3 = ( value & 0xf0 ) >> 8; p4 = value & 0xf; visca_init_command_packet_4( out_data, VISCA_COMMAND_IRIS_DIRECT, 0, 0, p3, p4 ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_iris( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 7; visca_init_inq_packet( out_data, VISCA_COMMAND_IRIS_DIRECT ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { property->value = ( in_data[4] * 0x10 + in_data[5] ); } property->flags = UNICAP_FLAGS_MANUAL; return status; } unicap_status_t visca_set_ae_mode( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; unsigned char param = 0xff; int i; out_bytes = 6; in_bytes = 6; for( i = 0; ae_modes[i].param != -1; i++ ) { if( !strcmp( property->menu_item, ae_modes[i].menu_item ) ) { param = ae_modes[i].param; break; } } if( param == 0xff ) { return STATUS_INVALID_PARAMETER; }; visca_init_command_packet_1( out_data, VISCA_COMMAND_AE_MODE, param ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); return status; } unicap_status_t visca_get_ae_mode( vid21394handle_t vid21394handle, unicap_property_t *property ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[8]; unicap_status_t status; out_bytes = 5; in_bytes = 4; visca_init_inq_packet( out_data, VISCA_COMMAND_AE_MODE ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( SUCCESS( status ) ) { status = visca_check_inq_response( in_data ); property->flags = UNICAP_FLAGS_MANUAL; switch( in_data[2] ) { case VISCA_AE_MODE_MANUAL: { strcpy( property->menu_item, VISCA_AE_MENU_ITEM_MANUAL ); } break; case VISCA_AE_MODE_FULL_AUTO: { strcpy( property->menu_item, VISCA_AE_MENU_ITEM_FULL_AUTO ); } break; case VISCA_AE_MODE_SHUTTER_PRIO: { strcpy( property->menu_item, VISCA_AE_MENU_ITEM_SHUTTER_PRIO ); } break; case VISCA_AE_MODE_IRIS_PRIO: { strcpy( property->menu_item, VISCA_AE_MENU_ITEM_IRIS_PRIO ); } break; case VISCA_AE_MODE_BRIGHT: { strcpy( property->menu_item, VISCA_AE_MENU_ITEM_BRIGHT ); } break; default: { strcpy( property->menu_item, "Unknown" ); } break; } } return status; } unicap_status_t visca_reenumerate_properties( vid21394handle_t vid21394handle, int *count ) { *count = ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ); return STATUS_SUCCESS; } unicap_status_t visca_enumerate_properties( unicap_property_t *property, int index ) { if( ( index < 0 ) || ( index >= ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ) ) ) { return STATUS_NO_MATCH; } unicap_copy_property( property, &visca_property_table[index].property ); return STATUS_SUCCESS; } unicap_status_t visca_set_property( vid21394handle_t vid21394handle, unicap_property_t *property ) { int i; unicap_status_t status = STATUS_INVALID_PARAMETER; for( i = 0; i < ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ); i++ ) { if( !strcmp( visca_property_table[i].property.identifier, property->identifier ) ) { status = visca_property_table[i].set_function( vid21394handle, property ); break; } } return status; } unicap_status_t visca_get_property( vid21394handle_t vid21394handle, unicap_property_t *property ) { int i; unicap_status_t status = STATUS_INVALID_PARAMETER; for( i = 0; i < ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ); i++ ) { if( !strcmp( visca_property_table[i].property.identifier, property->identifier ) ) { unicap_copy_property( property, & visca_property_table[i].property ); status = visca_property_table[i].get_function( vid21394handle, property ); break; } } return status; } unicap_status_t visca_check_camera( vid21394handle_t vid21394handle, visca_camera_type_t *type ) { int out_bytes, in_bytes; unsigned char out_data[8]; unsigned char in_data[10]; unicap_status_t status = STATUS_FAILURE; *type = VISCA_CAMERA_TYPE_NONE; out_bytes = 5; in_bytes = 10; visca_init_device_type_inq_packet( out_data ); vid21394_rs232_set_baudrate( vid21394handle, 9600 ); visca_htofla( out_data, out_bytes ); status = vid21394_rs232_io( vid21394handle, out_data, out_bytes, in_data, in_bytes ); if( !SUCCESS( status ) ) { TRACE( "Get camera type failed\n" ); return status; } // Check Vendor ID if( ( in_data[2] != 0x0 ) || ( in_data[3] != 0x20 ) ) { TRACE( "Wrong Vendor ID\n" ); } else if( ( in_data[4] != 0x4 ) ) // Check Model ID { TRACE( "Unknown camera type!\n" ); *type = VISCA_CAMERA_TYPE_UNKNOWN; } else { *type = VISCA_CAMERA_TYPE_FCB_IX47; } return status; } libunicap/cpi/vid21394/visca_private.h0000644000175000017500000000706113164711411020231 0ustar zmoelnigzmoelnig#ifndef __VISCA_PRIVATE_H__ #define __VISCA_PRIVATE_H__ /* unicap Copyright (C) 2004 Arne Caspari ( arne_caspari@users.sourceforge.net ) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define VISCA_COMMAND_ZOOM 0x07 #define VISCA_COMMAND_ZOOM_DIRECT 0x47 #define VISCA_COMMAND_FOCUS 0x08 #define VISCA_COMMAND_FOCUS_AUTO 0x38 #define VISCA_COMMAND_FOCUS_DIRECT 0x48 #define VISCA_COMMAND_FOCUS_MODE_INQ 0x57 #define VISCA_FOCUS_AUTO 0x02 #define VISCA_FOCUS_MANUAL 0x03 #define VISCA_COMMAND_AE_MODE 0x39 #define VISCA_AE_MODE_FULL_AUTO 0x00 #define VISCA_AE_MODE_MANUAL 0x03 #define VISCA_AE_MODE_SHUTTER_PRIO 0x0A #define VISCA_AE_MODE_IRIS_PRIO 0x0B #define VISCA_AE_MODE_BRIGHT 0x0D #define VISCA_AE_MENU_ITEM_FULL_AUTO "Full Auto" #define VISCA_AE_MENU_ITEM_MANUAL "Manual" #define VISCA_AE_MENU_ITEM_SHUTTER_PRIO "Shutter Priority" #define VISCA_AE_MENU_ITEM_IRIS_PRIO "Iris Priority" #define VISCA_AE_MENU_ITEM_BRIGHT "Bright Mode" #define VISCA_COMMAND_SHUTTER_DIRECT 0x4A #define VISCA_COMMAND_IRIS_DIRECT 0x4B #define VISCA_COMMAND_GAIN_DIRECT 0x4C #define VISCA_COMMAND_WHITE_BALANCE 0x35 #define VISCA_WHITE_BALANCE_AUTO 0x00 #define VISCA_WHITE_BALANCE_INDOOR 0x01 #define VISCA_WHITE_BALANCE_OUTDOOR 0x02 #define VISCA_COMMAND_COMPLETE 0x50 unicap_status_t visca_set_white_balance( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_white_balance( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_set_zoom( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_zoom( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_set_focus( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_focus( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_set_gain( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_gain( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_set_shutter( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_shutter( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_set_iris( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_iris( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_set_ae_mode( vid21394handle_t vid21394handle, unicap_property_t *property ); unicap_status_t visca_get_ae_mode( vid21394handle_t vid21394handle, unicap_property_t *property ); #endif//__VISCA_PRIVATE_H__ libunicap/cpi/vid21394/vid21394_cpi.h0000644000175000017500000000417513164711411017415 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __VID21394_CPI_H__ #define __VID21394_CPI_H__ int cpi_enumerate_devices( unicap_device_t *device, int index ); int cpi_open( void **cpi_data, unicap_device_t *device ); int cpi_close( void *cpi_data ); unicap_status_t cpi_reenumerate_formats( void *cpi_data, int *count ); int cpi_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ); int cpi_set_format( void *cpi_data, unicap_format_t *format ); unicap_status_t cpi_get_format( void *cpi_data, unicap_format_t *format ); unicap_status_t cpi_reenumerate_properties( void *cpi_data, int *count ); unicap_status_t cpi_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ); unicap_status_t cpi_set_property( void *cpi_data, unicap_property_t *property ); unicap_status_t cpi_get_property( void *cpi_data, unicap_property_t *property ); unicap_status_t cpi_capture_start( void *cpi_data ); unicap_status_t cpi_capture_stop( void *cpi_data ); unicap_status_t cpi_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ); unicap_status_t cpi_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); unicap_status_t cpi_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); unicap_status_t cpi_poll_buffer( void *cpi_data, int *count ); #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #endif//__VID21394_CPI_H__ libunicap/cpi/vid21394/1394util.c0000644000175000017500000003257613164711411016674 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include // for ntohl #include #include "config.h" #if RAW1394_1_1_API #include #include #else #include #include #endif #include #include #include #include "1394util.h" #include #if VID21394_DEBUG #define DEBUG #endif #include #define MAXTRIES 20 #define DELAY 10000 #define EXTCODE_COMPARE_SWAP 0x2 #define MAX_BANDWIDTH 0x1333 // Check this! Should be 0x1000 ??? int cooked1394_read( raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *buffer ) { int retval, i; for( i=0; i < MAXTRIES; i++ ) { retval = raw1394_read( handle, node, addr, length, buffer ); if( retval >= 0 ) { return retval; } if( errno != EAGAIN ) { break; } usleep(DELAY); } #ifdef DEBUG perror("Error while reading from IEEE1394: "); #endif return retval; } int cooked1394_write( raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *data) { int retval, i; for( i=0; i < MAXTRIES; i++ ) { retval = raw1394_write( handle, node, addr, length, data ); if( retval >= 0 ) { return retval; } if( errno != EAGAIN ){ break; } usleep( DELAY ); } #ifdef DEBUG perror( "Error while writing to IEEE1394: " ); #endif return retval; } /* * Obtain the global unique identifier of a node from its configuration ROM. * The GUID can also be read from a filled out Rom_info structure, but this * method is of course faster than reading the whole configuration ROM and can * for instance be used to obtain a hash key for caching Rom_info structures * in memory. * IN: phyID: Physical ID of the node to read from * hi: Pointer to an integer which should receive the HI quadlet * hi: Pointer to an integer which should receive the LOW quadlet */ unsigned long long get_guid(raw1394handle_t handle, int phyID ) { unsigned int hiquad; unsigned int loquad; unsigned long long guid = 0; if ( cooked1394_read( handle, 0xffC0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x0C, 4, &hiquad ) < 0 ) { return 0; } if ( cooked1394_read( handle, 0xffC0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x10, 4, &loquad ) < 0 ) { return 0; } hiquad = ntohl( hiquad ); loquad = ntohl( loquad ); guid = ( ( unsigned long long ) hiquad ) << 32; guid += loquad; return guid; } unsigned int get_unit_spec_ID( raw1394handle_t handle, int phyID ) { unsigned int unit_dir_offset; unsigned int spec_ID; if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24, 4, &unit_dir_offset ) < 0 ) { TRACE( "failed to read unit_dir _offset\n" ); return 0; } unit_dir_offset = ntohl( unit_dir_offset ); unit_dir_offset &= 0x00ffffff; TRACE( "unit_dir_offset: %x\n", unit_dir_offset ); if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24 + unit_dir_offset + 0x8, 4, &spec_ID ) < 0 ) { return 0; } spec_ID = ntohl( spec_ID ); spec_ID &= 0x00ffffff; return spec_ID; } unsigned int get_unit_sw_version( raw1394handle_t handle, int phyID ) { unsigned int unit_dir_offset; unsigned int sw_version; if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24, 4, &unit_dir_offset ) < 0 ) { TRACE( "failed to read unit_dir _offset\n" ); return 0; } unit_dir_offset = ntohl( unit_dir_offset ); unit_dir_offset &= 0x00ffffff; TRACE( "unit_dir_offset: %x\n", unit_dir_offset ); if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24 + unit_dir_offset + 0xc, 4, &sw_version ) < 0 ) { return 0; } sw_version = ntohl( sw_version ); sw_version &= 0x00ffffff; return sw_version; } /* allocate the first free channel for isochronous transmission using compare & swap returns: < 0 if channel could not be allocated or the allocated channel */ int _1394util_find_free_channel( raw1394handle_t raw1394handle ) { quadlet_t buffer; int channel = -1; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_CHANNELS_AVAILABLE_LO\n" ); #endif return -1; } buffer = ntohl( buffer ); for( channel = 0; ( !( buffer & ( 1 << channel ) ) ) && channel < 32; channel++ ) { } if( channel > 31 ) // none found in the lower range { if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_CHANNELS_AVAILABLE_HI\n" ); #endif return -1; } buffer = ntohl( buffer ); for( channel = 0; ( !( buffer & ( 1< 31 if( channel > 63 ) { #ifdef DEBUG fprintf( stderr, "No free channel found\n" ); #endif return -1; } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer & ~( 1< raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { #ifdef DEBUG fprintf( stderr, "Channel allocation failed\n" ); #endif return -1; } // is the following thread safe? I do not think so! if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to read back available channels\n" ); #endif return -1; } if( buffer != data ) { #ifdef DEBUG fprintf( stderr, "Validation of channel failed\n" ); #endif return -1; } } return channel; } /* free a channel */ unicap_status_t _1394util_free_channel( raw1394handle_t raw1394handle, int channel ) { quadlet_t buffer; if( 0 <= cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { int channel_bit = channel > 31 ? channel - 32 : channel; quadlet_t data, arg, result; buffer = htonl( buffer ); if( buffer & ( 1< raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { #ifdef DEBUG fprintf( stderr, "Failed to free channel\n" ); #endif return STATUS_FAILURE; } if( arg != htonl( buffer ) ) { #ifdef DEBUG fprintf( stderr, "Free channel validation failed\n" ); #endif return STATUS_FAILURE; } return STATUS_SUCCESS; } TRACE( "Read failed\n" ); return STATUS_FAILURE; } /* try to allocate channel on the bus returns: status */ unicap_status_t _1394util_allocate_channel( raw1394handle_t raw1394handle, int channel ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_CHANNELS_AVAILABLE_LO\n" ); #endif return STATUS_FAILURE; } buffer = ntohl( buffer ); if( channel > 31 ) // none found in the lower range { if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_CHANNELS_AVAILABLE_HI\n" ); #endif return -1; } buffer = ntohl( buffer ); }//if( channel > 31 if( channel > 63 ) { #ifdef DEBUG fprintf( stderr, "Channel number too high\n" ); #endif return STATUS_INVALID_PARAMETER; } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer & ~( 1< raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { #ifdef DEBUG fprintf( stderr, "Channel allocation failed\n" ); #endif return STATUS_FAILURE; } if( arg != buffer ) { #ifdef DEBUG fprintf( stderr, "Allocate channel validation failed\n" ); #endif return STATUS_FAILURE; } } return STATUS_SUCCESS; } unicap_status_t _1394util_allocate_bandwidth( raw1394handle_t raw1394handle, int bandwidth ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_BANDWIDTH_AVAILABLE\n" ); #endif return STATUS_FAILURE; } buffer = ntohl( buffer ); if( (int)(buffer - bandwidth) < 0 ) { #ifdef DEBUG fprintf( stderr, "Insufficient bandwidth\n" ); #endif return STATUS_INSUFFICIENT_BANDWIDTH; } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer - bandwidth ); if( 0 > raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { #ifdef DEBUG fprintf( stderr, "Failed to allocate bandwidth\n" ); #endif return STATUS_FAILURE; } if( arg != htonl( buffer ) ) { #ifdef DEBUG fprintf( stderr, "Allocate bandwidth validation failed\n" ); #endif return STATUS_FAILURE; } } return STATUS_SUCCESS; } /* free bandwidth no checking if more bw than allocated is freed! */ int _1394util_free_bandwidth( raw1394handle_t raw1394handle, int bandwidth ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_BANDWIDTH_AVAILABLE\n" ); #endif return STATUS_FAILURE; } buffer = ntohl( buffer ); #ifdef DEBUG fprintf( stderr, "Available bandwidth: 0x%x ( %d )\n", buffer, buffer ); #endif if( (int)(buffer + bandwidth) > MAX_BANDWIDTH ) { // just a warning! #ifdef DEBUG fprintf( stderr, "Freeing of bandwidth gives more than the maximum allowed ( or the bus is > 400Mbps )\n" ); #endif } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer + bandwidth ); if( 0 > raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { #ifdef DEBUG fprintf( stderr, "Failed to allocate bandwidth\n" ); #endif return STATUS_FAILURE; } if( arg != htonl( buffer ) ) { #ifdef DEBUG fprintf( stderr, "Allocate bandwidth validation failed: arg = %x, buffer = %x\n", arg, htonl( buffer ) ); #endif return STATUS_FAILURE; } } return STATUS_SUCCESS; } /* return the bw available on the bus. for convenience only, value could change any time */ int _1394util_get_available_bandwidth( raw1394handle_t raw1394handle ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, sizeof( quadlet_t ), &buffer ) ) { #ifdef DEBUG fprintf( stderr, "Failed to get CSR_BANDWIDTH_AVAILABLE\n" ); #endif return -1; } buffer = ntohl( buffer ); return buffer; } libunicap/cpi/vid21394/vid21394_cpi.c0000644000175000017500000010154713164711411017411 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include "unicap.h" #include "unicap_status.h" #include "unicap_cpi.h" #include "unicap_cpi_std_struct.h" #include #include "vid21394_cpi.h" #include "vid21394.h" #include "vid21394_base.h" #include "visca.h" #if VID21394_DEBUG #define DEBUG #endif #include "debug.h" #include <1394util.h> enum property_enum{ PROP_BRIGHTNESS = 0, PROPERTY_COUNT }; #define EXTRA_INPUTS #define VIDEO_SOURCE_COMPOSITE_1 "Composite 1" #define VIDEO_SOURCE_COMPOSITE_2 "Composite 2" #define VIDEO_SOURCE_COMPOSITE_3 "Composite 3" #define VIDEO_SOURCE_COMPOSITE_4 "Composite 4" #define VIDEO_SOURCE_SVHS "SVHS" #define VIDEO_SOURCE_AUTO "Auto" #define VIDEO_SOURCE_NONE "None" #define video_source_default_item "Composite 1" char *video_sources[] = { VIDEO_SOURCE_COMPOSITE_1, VIDEO_SOURCE_COMPOSITE_2, #ifdef EXTRA_INPUTS VIDEO_SOURCE_COMPOSITE_3, VIDEO_SOURCE_COMPOSITE_4, #endif VIDEO_SOURCE_SVHS, VIDEO_SOURCE_AUTO, VIDEO_SOURCE_NONE }; #define video_norm_default_item "NTSC" char *video_norm_menu_items[] = { "PAL", "NTSC" }; unicap_rect_t vid21394_pal_video_sizes[] = { {0, 0, 320,240}, {0, 0, 640, 480}, {0, 0, 768, 576} }; unicap_rect_t vid21394_ntsc_video_sizes[] = { {0, 0, 320,240}, {0, 0, 640, 480} }; unicap_format_t vid21394_formats[] = { // UYVY { "UYVY", // name {0, 0, 768,576},{0, 0, 320,240},{0, 0, 768,576}, -1,-1, vid21394_pal_video_sizes, 3, 16, // width, height, bpp FOURCC('U','Y','V','Y'), // fourcc 0, // flags 0, 320*240*2}, // buffer size // YUY2 { "YUY2", // name {0, 0, 768,576},{0, 0, 320,240},{0, 0, 768,576}, -1,-1, vid21394_pal_video_sizes, 3, 16, // width, height, bpp FOURCC('Y','U','Y','2'), // fourcc 0, // flags 0, 320*240*2}, // buffer size // Y411 { "Y411", {0, 0, 768,576},{0, 0, 320,240},{0, 0, 768,576}, -1,-1, vid21394_pal_video_sizes, 3, 12, FOURCC('Y','4','1','1'), 0, 0, 320*240*2 + ( 320*240 >> 1 ) }, // Y8 { "Grey", {0, 0, 768,576},{0, 0, 320,240},{0, 0, 768,576}, -1,-1, vid21394_pal_video_sizes, 3, 8, FOURCC('Y','8','0','0'), 0, 0, 320*240 }, }; unicap_property_t vid21394_properties[] = { { "brightness", S_PPTY_INFO_VIDEO, // name, class, unit {0.5}, // default value {{ 0.0, 1.0 }}, // range 0.01, // stepping UNICAP_PROPERTY_TYPE_RANGE, UNICAP_FLAGS_MANUAL, UNICAP_FLAGS_MANUAL, 0, // property data 0, // property data size }, { "contrast", S_PPTY_INFO_VIDEO, // name, class, unit {0.5}, // default value {{ 0.0, 1.0 }}, // range 0.01, // stepping UNICAP_PROPERTY_TYPE_RANGE, UNICAP_FLAGS_MANUAL, UNICAP_FLAGS_MANUAL, 0, // property data 0, // property data size }, { identifier: "force odd/even", category: "device", unit: "", relations: NULL, relations_count: 0, { value: 0.0}, // default value { range: { min: 0.0, max: 1.0 }}, // range stepping: 1.0, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "source", category: "video", unit: "", relations: NULL, relations_count: 0, { menu_item: { video_source_default_item } }, // default value { menu: { menu_items: video_sources, menu_item_count: sizeof( video_sources ) / sizeof( char * ) }}, // range 0.01, // stepping UNICAP_PROPERTY_TYPE_MENU, UNICAP_FLAGS_MANUAL, UNICAP_FLAGS_MANUAL, 0, // property data 0, // property data size }, { identifier: "video norm", category: "video", unit: "", relations: NULL, relations_count: 0, { menu_item: { video_norm_default_item } }, { menu: { menu_items: video_norm_menu_items, menu_item_count: sizeof( video_norm_menu_items ) / sizeof( char * ) }, }, stepping: 0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0, }, { identifier: "rs232 io", category: "device", unit: "", relations: NULL, relations_count: 0, { value: 0 }, // default value { range: { min: 0, max: 0 } }, // range stepping: 0, // stepping type: UNICAP_PROPERTY_TYPE_DATA, flags: 0, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0, }, { identifier: "rs232 baud rate", category: "device", unit: "", relations: NULL, relations_count: 0, { value: 0 }, // default value { range: { min: 0, max: 4 } }, // range stepping: 1.0, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: 0, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "link speed", category: "device", unit: "", relations: NULL, relations_count: 0, { value: 0.0}, { range: { min: 0.0, max: 2.0}}, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: 0, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0, }, { identifier: "firmware version", category: "device", unit: "", relations: NULL, relations_count: 0, { value: 0.0 }, // default value { range: { min: 0.0, max: 99999 }}, // range stepping: 1.0, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: 0, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, #if VID21394_BOOTLOAD { identifier: "enter bootload", category: "device", unit: "", relations: NULL, relations_count: 0, { value: 0.0 }, // default value { range: { min: 0.0, max: 1.0 }}, // range stepping: 1.0, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: 0, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, #endif }; struct _vid21394_data_struct { int instance; int device; int format; int capture_running; unicap_property_t *current_properties; unicap_format_t current_formats[4]; vid21394handle_t vid21394handle; unicap_queue_t *in_queue; int in_queue_lock; unicap_queue_t *out_queue; int out_queue_lock; char rs232_buffer[1024]; int enable_visca_support; }; typedef struct _vid21394_data_struct vid21394_data_t; int g_instance_count = 0; static unicap_status_t vid21394cpi_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ); static struct _unicap_cpi cpi_s = { cpi_version: 1<<16, cpi_capabilities: 0x3ffff, cpi_enumerate_devices: cpi_enumerate_devices, cpi_open: cpi_open, cpi_close: cpi_close, cpi_reenumerate_formats: cpi_reenumerate_formats, cpi_enumerate_formats: cpi_enumerate_formats, cpi_set_format: cpi_set_format, cpi_get_format: cpi_get_format, cpi_reenumerate_properties: cpi_reenumerate_properties, cpi_enumerate_properties: cpi_enumerate_properties, cpi_set_property: cpi_set_property, cpi_get_property: cpi_get_property, cpi_capture_start: cpi_capture_start, cpi_capture_stop: cpi_capture_stop, cpi_queue_buffer: cpi_queue_buffer, cpi_dequeue_buffer: cpi_dequeue_buffer, cpi_wait_buffer: cpi_wait_buffer, cpi_poll_buffer: cpi_poll_buffer, cpi_set_event_notify: vid21394cpi_set_event_notify, }; #if ENABLE_STATIC_CPI void unicap_vid21394_register_static_cpi( struct _unicap_cpi **cpi ) { *cpi = &cpi_s; } #else unicap_status_t cpi_register( struct _unicap_cpi *reg_data ) { memcpy( reg_data, &cpi_s, sizeof( struct _unicap_cpi ) ); /* reg_data->cpi_version = 1<<16; */ /* reg_data->cpi_capabilities = 0x3ffff; */ /* reg_data->cpi_enumerate_devices = cpi_enumerate_devices; */ /* reg_data->cpi_open = cpi_open; */ /* reg_data->cpi_close = cpi_close; */ /* reg_data->cpi_reenumerate_formats = cpi_reenumerate_formats; */ /* reg_data->cpi_enumerate_formats = cpi_enumerate_formats; */ /* reg_data->cpi_set_format = cpi_set_format; */ /* reg_data->cpi_get_format = cpi_get_format; */ /* reg_data->cpi_reenumerate_properties = cpi_reenumerate_properties; */ /* reg_data->cpi_enumerate_properties = cpi_enumerate_properties; */ /* reg_data->cpi_set_property = cpi_set_property; */ /* reg_data->cpi_get_property = cpi_get_property; */ /* reg_data->cpi_capture_start = cpi_capture_start; */ /* reg_data->cpi_capture_stop = cpi_capture_stop; */ /* reg_data->cpi_queue_buffer = cpi_queue_buffer; */ /* reg_data->cpi_dequeue_buffer = cpi_dequeue_buffer; */ /* reg_data->cpi_wait_buffer = cpi_wait_buffer; */ /* reg_data->cpi_poll_buffer = cpi_poll_buffer; */ /* reg_data->cpi_set_event_notify = vid21394cpi_set_event_notify; */ return STATUS_SUCCESS; } #endif//ENABLE_STATIC_CPI int cpi_open( void **cpi_data, unicap_device_t *device ) { vid21394_data_t *data; unsigned long long sernum = 0; raw1394handle_t raw1394handle; int i, found = 0; int port, num_ports = 0; *cpi_data = malloc( sizeof( struct _vid21394_data_struct ) ); if( !*cpi_data ) { return STATUS_NO_MEM; } data = (vid21394_data_t *)*cpi_data; memset( data, 0x0, sizeof( struct _vid21394_data_struct ) ); data->current_properties = malloc( sizeof( vid21394_properties ) ); if( !data->current_properties ) { free( *cpi_data ); return STATUS_NO_MEM; } for( i = 0; i < ( sizeof( vid21394_properties ) / sizeof( unicap_property_t ) ); i++ ) { unicap_copy_property( &data->current_properties[i], &vid21394_properties[i] ); } raw1394handle = raw1394_new_handle(); if( !raw1394handle ) { TRACE( "failed to get raw1394 handle\n" ); return STATUS_NO_DEVICE; } num_ports = raw1394_get_port_info( raw1394handle, NULL, 0 ); raw1394_destroy_handle( raw1394handle ); for( port = 0; ( port < num_ports ) && !found; port++ ) { raw1394handle = raw1394_new_handle_on_port( port ); for( i = 0; i < raw1394_get_nodecount( raw1394handle ); i++ ) { if( ( get_unit_spec_ID( raw1394handle, i ) == 0x748 ) && ( ( get_unit_sw_version( raw1394handle, i ) == 0x526f6e ) || ( get_unit_sw_version( raw1394handle, i ) == 0x526f6f ) ) ) { char identifier[128]; sprintf( identifier, "DFG/1394-1 %llx", get_guid( raw1394handle, i ) & 0xffffffff ); if( !strcmp( identifier, device->identifier ) ) { sernum = get_guid( raw1394handle, i ); found = 1; break; } } } raw1394_destroy_handle( raw1394handle ); } if( ( data->vid21394handle = vid21394_open( sernum ) ) == VID21394_INVALID_HANDLE_VALUE ) { free( data ); TRACE( "failed to open vid21294\n" ); return STATUS_FAILURE; } g_instance_count++; data->instance = g_instance_count; data->device = 0; data->format = -1; data->capture_running = 0; data->in_queue = ucutil_queue_new(); data->out_queue = ucutil_queue_new(); cpi_reenumerate_formats( data, &i ); if( VID21394_DETECT_21CF04 && ( data->vid21394handle->firmware_version >= 0x303 ) ) { visca_camera_type_t cam_type; if( SUCCESS( visca_check_camera( data->vid21394handle, &cam_type ) ) ) { if( cam_type == VISCA_CAMERA_TYPE_FCB_IX47 ) { TRACE( "FOUND FCB camera\n" ); data->enable_visca_support = 1; } } } #if VID21394_VISCA data->enable_visca_support = 1; #endif return STATUS_SUCCESS; } int cpi_close( void *cpi_data ) { vid21394_data_t *data = cpi_data; ucutil_destroy_queue( data->in_queue ); ucutil_destroy_queue( data->out_queue ); if( data->vid21394handle->unicap_handle ) { free( data->vid21394handle->unicap_handle ); } vid21394_close( data->vid21394handle ); g_instance_count--; free( data ); return STATUS_SUCCESS; } int cpi_enumerate_devices( unicap_device_t *device, int index ) { int node, port, num_ports = 0; int tmp_index = -1; int found_node = -1, found_port = -1; raw1394handle_t raw1394handle; unicap_status_t status = STATUS_SUCCESS; if( !device ) { return STATUS_INVALID_PARAMETER; } raw1394handle = raw1394_new_handle(); if( !raw1394handle ) { TRACE( "failed to get raw1394 handle\n" ); return STATUS_NO_DEVICE; } num_ports = raw1394_get_port_info( raw1394handle, NULL, 0 ); raw1394_destroy_handle( raw1394handle ); for( port = 0; ( port < num_ports ) && tmp_index != index; port++ ) { int nodes; raw1394handle = raw1394_new_handle_on_port( port ); nodes = raw1394_get_nodecount( raw1394handle ); TRACE( "port: %d, nodes: %d, tmp_index: %d index: %d\n", port, nodes, tmp_index, index ); for( node = 0; ( tmp_index != index ) && ( node < nodes ); node++ ) { if( ( get_unit_spec_ID( raw1394handle, node ) == 0x748 ) && ( ( get_unit_sw_version( raw1394handle, node ) == 0x526f6e ) || ( get_unit_sw_version( raw1394handle, node ) == 0x526f6f ) ) ) { TRACE( "DFG1394 found on port: %d node: %d\n", port, node ); tmp_index++; if( tmp_index == index ) { found_node = node; found_port = port; } } } raw1394_destroy_handle( raw1394handle ); } if( found_node != -1 ) { raw1394handle = raw1394_new_handle_on_port( found_port ); device->model_id = get_guid( raw1394handle, found_node ); TRACE( "get guid port: %d node: %d\n", found_port, found_node ); sprintf( device->identifier, "DFG/1394-1 %llx", device->model_id & 0xffffffff ); strcpy( device->model_name, "DFG/1394-1" ); strcpy( device->vendor_name, "unicap"); device->vendor_id = 0xffff0000; device->flags = UNICAP_CPI_SERIALIZED; strcpy( device->device, "/dev/raw1394" ); status = STATUS_SUCCESS; raw1394_destroy_handle( raw1394handle ); } else { status = STATUS_NO_DEVICE; } return status; } unicap_status_t cpi_reenumerate_formats( void *cpi_data, int *count ) { int nr_formats = sizeof( vid21394_formats ) / sizeof( unicap_format_t ); vid21394_data_t *data = cpi_data; enum vid21394_frequency freq; vid21394_get_frequency( data->vid21394handle, &freq ); if( freq == VID21394_FREQ_50 ) { int i; for( i = 0; i < nr_formats; i++ ) { vid21394_formats[i].size.width = 768; vid21394_formats[i].max_size.width = 768; vid21394_formats[i].size.height = 576; vid21394_formats[i].max_size.height = 576; vid21394_formats[i].sizes = vid21394_pal_video_sizes; vid21394_formats[i].size_count = sizeof( vid21394_pal_video_sizes ) / sizeof( unicap_rect_t ); } } else { int i; for( i = 0; i < nr_formats; i++ ) { vid21394_formats[i].size.width = 640; vid21394_formats[i].max_size.width = 640; vid21394_formats[i].size.height = 480; vid21394_formats[i].max_size.height = 480; vid21394_formats[i].sizes = vid21394_ntsc_video_sizes; vid21394_formats[i].size_count = sizeof( vid21394_ntsc_video_sizes ) / sizeof( unicap_rect_t ); } } if (count) *count = nr_formats; memcpy( data->current_formats, vid21394_formats, sizeof( unicap_format_t ) * nr_formats ); return STATUS_SUCCESS; } int cpi_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ) { int nr_formats = sizeof( vid21394_formats ) / sizeof( unicap_format_t ); vid21394_data_t *data = cpi_data; if( !data || !format ) { return STATUS_INVALID_PARAMETER; } cpi_reenumerate_formats( cpi_data, NULL ); if( ( index >= 0 ) && ( index < nr_formats ) ) { memcpy( format, &data->current_formats[index], sizeof( unicap_format_t ) ); } else { return STATUS_NO_MATCH; } return STATUS_SUCCESS; } int cpi_set_format( void *cpi_data, unicap_format_t *format ) { int format_index = 0; int nr_formats = sizeof( vid21394_formats ) / sizeof( unicap_format_t ); vid21394_data_t *data = cpi_data; vid21394handle_t vid21394handle = data->vid21394handle; enum vid21394_video_mode mode; unicap_status_t status; TRACE( "cpi_set_format\n" ); cpi_reenumerate_formats( cpi_data, NULL ); // search for a matching name in the formats list while( ( format_index < nr_formats ) && ( strcmp( format->identifier, vid21394_formats[format_index].identifier ) ) ) { format_index++; } // check if actually found a match or the end of the list was reached if( format_index == nr_formats ) { return STATUS_NO_MATCH; } // remember the format data->format = format_index; if( vid21394handle->system_buffer ) { free( vid21394handle->system_buffer ); vid21394handle->system_buffer = NULL; } switch( format->fourcc ) { case FOURCC( 'U', 'Y', 'V', 'Y' ): if( format->size.width == 320 ) { mode = VID21394_UYVY_320x240; break; } else if( format->size.width == 640 ) { mode = VID21394_UYVY_640x480; break; } else if( format->size.width == 768 ) { mode = VID21394_UYVY_768x576; break; } else { TRACE( "invalid mode\n" ); return STATUS_FAILURE; } break; case FOURCC( 'Y', 'U', 'Y', '2' ): if( format->size.width == 320 ) { mode = VID21394_YUY2_320x240; break; } else if( format->size.width == 640 ) { mode = VID21394_YUY2_640x480; break; } else if( format->size.width == 768 ) { mode = VID21394_YUY2_768x576; break; } else { TRACE( "invalid mode\n" ); return STATUS_FAILURE; } break; case FOURCC( 'Y', '4', '1', '1' ): if( format->size.width == 320 ) { mode = VID21394_Y41P_320x240; break; } else if( format->size.width == 640 ) { TRACE( "Y41P 640x480\n" ); mode = VID21394_Y41P_640x480; break; } else if( format->size.width == 768 ) { mode = VID21394_Y41P_768x576; break; } else { TRACE( "invalid mode\n" ); return STATUS_FAILURE; } break; case FOURCC( 'Y', '8', '0', '0' ): if( format->size.width == 320 ) { mode = VID21394_Y_320x240; break; } else if( format->size.width == 640 ) { mode = VID21394_Y_640x480; break; } else if( format->size.width == 768 ) { mode = VID21394_Y_768x576; break; } else { TRACE( "invalid mode\n" ); return STATUS_FAILURE; } break; default: TRACE( "invalid mode\n" ); return STATUS_FAILURE; break; } if( data->capture_running ) { status = cpi_capture_stop( cpi_data ); if( SUCCESS( status ) ) { status = vid21394_set_video_mode( data->vid21394handle, mode ); if( SUCCESS( status ) ) { status = cpi_capture_start( cpi_data ); } } } else { status = vid21394_set_video_mode( data->vid21394handle, mode ); } format->buffer_size = format->size.width * format->size.height * format->bpp / 8; data->current_formats[ format_index ].size.width = format->size.width; data->current_formats[ format_index ].size.height = format->size.height; unicap_copy_format( &vid21394handle->current_format, format ); if( vid21394handle->system_buffer ) { free( vid21394handle->system_buffer ); } if( format->buffer_type == UNICAP_BUFFER_TYPE_SYSTEM ) { vid21394handle->system_buffer = malloc( format->size.width * format->size.height * format->bpp / 8 ); vid21394handle->system_buffer_entry.data = vid21394handle->system_buffer; } return STATUS_SUCCESS; } unicap_status_t cpi_get_format( void *cpi_data, unicap_format_t *format ) { vid21394_data_t *data = cpi_data; cpi_reenumerate_formats( cpi_data, NULL ); if( data->format == -1 ) { return STATUS_NO_FORMAT; } unicap_copy_format( format, &data->vid21394handle->current_format ); format->buffer_size = ( format->size.width * format->size.height * format->bpp ) / 8; return STATUS_SUCCESS; } unicap_status_t cpi_reenumerate_properties( void *cpi_data, int *count ) { int nr_properties = sizeof( vid21394_properties ) / sizeof( unicap_property_t ); vid21394_data_t *data = cpi_data; *count = nr_properties; if( data->enable_visca_support ) { int visca_properties; if( SUCCESS( visca_reenumerate_properties( data->vid21394handle, &visca_properties ) ) ) { *count += visca_properties; } } return STATUS_SUCCESS; } unicap_status_t cpi_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ) { vid21394_data_t *data = cpi_data; int nr_properties = sizeof( vid21394_properties ) / sizeof( unicap_property_t ); unicap_status_t status = STATUS_SUCCESS; if( !data || !property ) { return STATUS_INVALID_PARAMETER; } if( index < 0 ) { return STATUS_NO_MATCH; } if( index >= nr_properties ) { if( data->enable_visca_support ) { status = visca_enumerate_properties( property, index - nr_properties ); /* TRACE( "%s\n", property->identifier ); */ } else { status = STATUS_NO_MATCH; } } else { memcpy( property, &vid21394_properties[index], sizeof( unicap_property_t) ); } return status; } unicap_status_t cpi_set_property( void *cpi_data, unicap_property_t *property ) { vid21394_data_t *data = cpi_data; int property_index = 0; int nr_properties = sizeof( vid21394_properties ) / sizeof( unicap_property_t ); unicap_status_t status = STATUS_FAILURE; if( !data || !property ) { TRACE( "invalid param\n" ); return STATUS_INVALID_PARAMETER; } while( ( property_index < nr_properties ) && ( strcmp( property->identifier, vid21394_properties[property_index].identifier ) ) ) { property_index++; } if( property_index == nr_properties ) { if( data->enable_visca_support ) { status = visca_set_property( data->vid21394handle, property ); return status; } else { TRACE( "no match, no VISCA\n" ); return STATUS_NO_MATCH; } } memcpy( &data->current_properties[property_index], property, sizeof( unicap_property_t ) ); if( !strcmp( property->identifier, "brightness" ) ) { status = vid21394_set_brightness( data->vid21394handle, property->value*255 ); } else if( !strcmp( property->identifier, "contrast" ) ) { status = vid21394_set_contrast( data->vid21394handle, property->value * 255 ); } else if( !strcmp( property->identifier, "force odd/even" ) ) { status = vid21394_set_force_odd_even( data->vid21394handle, property->value != 0 ); } else if( !strcmp( property->identifier, "source" ) ) { TRACE( "set source\n" ); if( !strcmp( property->menu_item, VIDEO_SOURCE_COMPOSITE_1 ) ) { status = vid21394_set_input_channel( data->vid21394handle, VID21394_INPUT_COMPOSITE_1 ); } else if( !strcmp( property->menu_item, VIDEO_SOURCE_COMPOSITE_2 ) ) { status = vid21394_set_input_channel( data->vid21394handle, VID21394_INPUT_COMPOSITE_2 ); } else if( !strcmp( property->menu_item, VIDEO_SOURCE_COMPOSITE_3 ) ) { status = vid21394_set_input_channel( data->vid21394handle, VID21394_INPUT_COMPOSITE_3 ); } else if( !strcmp( property->menu_item, VIDEO_SOURCE_COMPOSITE_4 ) ) { status = vid21394_set_input_channel( data->vid21394handle, VID21394_INPUT_COMPOSITE_4 ); } else if( !strcmp( property->menu_item, VIDEO_SOURCE_SVHS ) ) { status = vid21394_set_input_channel( data->vid21394handle, VID21394_INPUT_SVIDEO ); } else if( !strcmp( property->menu_item, VIDEO_SOURCE_AUTO ) ) { status = vid21394_set_input_channel( data->vid21394handle, VID21394_INPUT_AUTO ); } else { status = STATUS_INVALID_PARAMETER; } } else if( !strcmp( property->identifier, "video norm" ) ) { if( !strcmp( property->menu_item, video_norm_menu_items[0] ) ) { status = vid21394_set_frequency( data->vid21394handle, VID21394_FREQ_50 ); } else if( !strcmp( property->menu_item, video_norm_menu_items[1] ) ) { status = vid21394_set_frequency( data->vid21394handle, VID21394_FREQ_60 ); } } #if VID21394_BOOTLOAD else if( !strcmp( property->identifier, "enter bootload" ) ) { status = vid21394_enter_bootload( data->vid21394handle ); } #endif #if EXPERIMENTAL_FW else if( !strcmp( property->identifier, "rs232 io" ) ) { int size = property->value; TRACE( "send: out: %x, in: %x\n", property->property_data_size, size ); status = vid21394_rs232_io( data->vid21394handle, property->property_data, property->property_data_size, (unsigned char*)data->rs232_buffer, size ); property->property_data = data->rs232_buffer; property->property_data_size = size; } else if( !strcmp( property->identifier, "rs232 baud rate" ) ) { int rate = property->value; TRACE( "RS 232 BAUD RATE\n" ); status = vid21394_rs232_set_baudrate( data->vid21394handle, rate ); } else if( !strcmp( property->identifier, "link speed" ) ) { int speed = property->value; status = vid21394_set_link_speed( data->vid21394handle, speed ); } #endif else if( !strcmp( property->identifier, "firmware version" ) ) { property->value = data->vid21394handle->firmware_version; status = STATUS_SUCCESS; } else { TRACE( "unknown property!\n" ); } return status; } unicap_status_t cpi_get_property( void *cpi_data, unicap_property_t *property ) { vid21394_data_t *data = cpi_data; int property_index = 0; int nr_properties = sizeof( vid21394_properties ) / sizeof( unicap_property_t ); unsigned int value; unicap_status_t status = STATUS_FAILURE; if( !data || !property ) { return STATUS_INVALID_PARAMETER; } while( ( property_index < nr_properties ) && ( strcmp( property->identifier, vid21394_properties[property_index].identifier ) ) ) { property_index++; } if( property_index == nr_properties ) { if( data->enable_visca_support ) { status = visca_get_property( data->vid21394handle, property ); return status; } else { return STATUS_NO_MATCH; } } memcpy( property, &data->current_properties[property_index], sizeof( unicap_property_t ) ); if( !strcmp( property->identifier, "brightness" ) ) { status = vid21394_get_brightness( data->vid21394handle, &value ); property->value = (double)value / 255.0f; } else if( !strcmp( property->identifier, "contrast" ) ) { status = vid21394_get_contrast( data->vid21394handle, &value ); property->value = (double)value / 255.0f; } else if( !strcmp( property->identifier, "force odd/even" ) ) { status = vid21394_get_force_odd_even( data->vid21394handle, &value ); property->value = value; } else if( !strcmp( property->identifier, "source" ) ) { enum vid21394_input_channel channel; status = vid21394_get_input_channel( data->vid21394handle, &channel ); switch( channel ) { case VID21394_INPUT_COMPOSITE_1: strcpy( property->menu_item, VIDEO_SOURCE_COMPOSITE_1 ); break; case VID21394_INPUT_COMPOSITE_2: strcpy( property->menu_item, VIDEO_SOURCE_COMPOSITE_2 ); break; case VID21394_INPUT_COMPOSITE_3: strcpy( property->menu_item, VIDEO_SOURCE_COMPOSITE_3 ); break; case VID21394_INPUT_COMPOSITE_4: strcpy( property->menu_item, VIDEO_SOURCE_COMPOSITE_4 ); break; case VID21394_INPUT_SVIDEO: strcpy( property->menu_item, VIDEO_SOURCE_SVHS ); break; default: strcpy( property->menu_item, VIDEO_SOURCE_NONE ); break; } } else if( !strcmp( property->identifier, "video norm" ) ) { enum vid21394_frequency freq; status = vid21394_get_frequency( data->vid21394handle, &freq ); if( freq == VID21394_FREQ_50 ) { strcpy( property->menu_item, video_norm_menu_items[0] ); } else if( freq == VID21394_FREQ_60 ) { strcpy( property->menu_item, video_norm_menu_items[1] ); } else { strcpy( property->menu_item, "unknown" ); } } #if EXPERIMENTAL_FW else if( !strcmp( property->identifier, "rs232 io" ) ) { static char buffer[512]; property->property_data_size = 512; property->property_data = buffer; status = vid21394_read_rs232( data->vid21394handle, (unsigned char*)&buffer[0], (int*)&property->property_data_size ); } #endif else if( !strcmp( property->identifier, "firmware version" ) ) { property->value = data->vid21394handle->firmware_version; status = STATUS_SUCCESS; } return status; } unicap_status_t cpi_capture_start( void *cpi_data ) { vid21394_data_t *data = cpi_data; unicap_status_t status; status = vid21394_start_transmit( data->vid21394handle ); if( status ) { TRACE( "vid21394_start_transmit failed, err: %s\n", strerror( errno ) ); return STATUS_FAILURE; } data->vid21394handle->stop_capture = 0; errno = 0; if( pthread_create( &data->vid21394handle->capture_thread, NULL, (void*(*)(void*))vid21394_capture_thread, data->vid21394handle )) { perror( "create capture thread" ); return STATUS_FAILURE; } TRACE( "Capture start\n" ); data->capture_running = 1; return STATUS_SUCCESS; } unicap_status_t cpi_capture_stop( void *cpi_data ) { vid21394_data_t *data = cpi_data; unicap_status_t status; int was_running = data->capture_running; data->capture_running = 0; data->vid21394handle->stop_capture = 1; if( was_running ) { pthread_join( data->vid21394handle->capture_thread, NULL ); } status = vid21394_stop_transmit( data->vid21394handle ); TRACE( "Capture stop\n" ); return STATUS_SUCCESS; } unicap_status_t cpi_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ) { vid21394_data_t *data = cpi_data; unicap_queue_t *queue = malloc( sizeof( struct _unicap_queue ) ); queue->data = buffer; ucutil_insert_back_queue( data->in_queue, queue ); vid21394_queue_buffer( data->vid21394handle, buffer->data ); return STATUS_SUCCESS; } unicap_status_t cpi_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { vid21394_data_t *data = cpi_data; unicap_queue_t *entry; if( data->capture_running ) { return STATUS_IS_RECEIVING; } entry = ucutil_get_front_queue( data->in_queue ); if( !entry ) { return STATUS_NO_BUFFERS; } *buffer = entry->data; free( entry ); return STATUS_SUCCESS; } unicap_status_t cpi_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { vid21394_data_t *data = cpi_data; unicap_data_buffer_t *returned_buffer; unicap_queue_t *entry; unicap_status_t status; void *tmp_buffer; status = vid21394_wait_buffer( data->vid21394handle, &tmp_buffer ); if( status ) { TRACE( "vid21394_wait_buffer failed\n" ); return STATUS_FAILURE; } entry = ucutil_get_front_queue( data->in_queue ); if( !entry ) { return STATUS_NO_BUFFERS; } returned_buffer = ( unicap_data_buffer_t * ) entry->data; *buffer = returned_buffer; returned_buffer->data = tmp_buffer; cpi_get_format( data, &returned_buffer->format ); returned_buffer->buffer_size = returned_buffer->format.buffer_size; return STATUS_SUCCESS; } unicap_status_t cpi_poll_buffer( void *data, int *count ) { return STATUS_NOT_IMPLEMENTED; } unicap_status_t vid21394cpi_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ) { vid21394_data_t *data = cpi_data; data->vid21394handle->event_callback = func; data->vid21394handle->unicap_handle = unicap_handle; return STATUS_SUCCESS; } libunicap/cpi/vid21394/visca_property_table.h0000644000175000017500000001535113164711411021613 0ustar zmoelnigzmoelnig#ifndef __VISCA_PROPERTY_TABLE_H__ #define __VISCA_PROPERTY_TABLE_H__ /* unicap Copyright (C) 2004 Arne Caspari ( arne_caspari@users.sourceforge.net ) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include "vid21394_base.h" #include "visca_private.h" typedef unicap_status_t (*visca_property_function_t) ( vid21394handle_t vid21394handle, unicap_property_t *property ); struct visca_property { unicap_property_t property; visca_property_function_t set_function; visca_property_function_t get_function; }; typedef struct visca_property visca_property_t; #define VISCA_CAT_COLOR "color" #define VISCA_CAT_LENS "lens control" #define VISCA_CAT_EXPOSURE "exposure" #define VISCA_UNIT_KELVIN "k" #define VISCA_UNIT_NONE "" #define VISCA_ID_WHITE_BALANCE "White Balance" #define VISCA_WB_DEFAULT 5200 #define VISCA_WB_DEFAULT_FLAGS static double visca_white_balance_values[] = { 3800.0f, 5200.0f }; #define VISCA_ID_ZOOM "Zoom" #define VISCA_ZOOM_DEFAULT 0 #define VISCA_ZOOM_RANGE_MIN 0.0f #define VISCA_ZOOM_RANGE_MAX 50000.0f #define VISCA_ID_IRIS "Iris" #define VISCA_IRIS_DEFAULT 16 #define VISCA_IRIS_RANGE_MIN 0.0f #define VISCA_IRIS_RANGE_MAX 16.0f #define VISCA_ID_FOCUS "Focus" #define VISCA_FOCUS_DEFAULT 0 #define VISCA_FOCUS_RANGE_MIN 0.0f #define VISCA_FOCUS_RANGE_MAX 50000.0f #define VISCA_ID_SHUTTER "Shutter" #define VISCA_SHUTTER_DEFAULT 0 #define VISCA_SHUTTER_RANGE_MIN 0.0f #define VISCA_SHUTTER_RANGE_MAX 255.0f #define VISCA_ID_GAIN "Gain" #define VISCA_GAIN_DEFAULT 0 #define VISCA_GAIN_RANGE_MIN 0.0f #define VISCA_GAIN_RANGE_MAX 255.0f #define VISCA_ID_AUTOEXPOSURE_MODE "Auto Exposure Mode" #define VISCA_AUTOEXPOSURE_MODE_DEFAULT "Full Auto" #define VISCA_AUTOEXPOSURE_MODE_FLAGS UNICAP_FLAGS_MANUAL char *visca_autoexposure_mode_menu_items[] = { VISCA_AE_MENU_ITEM_FULL_AUTO, VISCA_AE_MENU_ITEM_MANUAL, VISCA_AE_MENU_ITEM_SHUTTER_PRIO, VISCA_AE_MENU_ITEM_IRIS_PRIO, VISCA_AE_MENU_ITEM_BRIGHT }; visca_property_t visca_property_table[] = { { property: { identifier: VISCA_ID_WHITE_BALANCE, category: VISCA_CAT_COLOR, unit: VISCA_UNIT_KELVIN, relations: 0, relations_count: 0, {value:VISCA_WB_DEFAULT}, {value_list:{visca_white_balance_values,sizeof( visca_white_balance_values ) / sizeof( double )}}, stepping: 0, type: UNICAP_PROPERTY_TYPE_VALUE_LIST, flags: UNICAP_FLAGS_AUTO, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: 0, property_data_size: 0 // data }, set_function: visca_set_white_balance, get_function: visca_get_white_balance, }, { property: { identifier: VISCA_ID_ZOOM, category: VISCA_CAT_LENS, unit: VISCA_UNIT_NONE, relations: 0, relations_count: 0, {value: VISCA_ZOOM_DEFAULT }, {range:{ VISCA_ZOOM_RANGE_MIN, VISCA_ZOOM_RANGE_MAX }}, stepping: 1.0f, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0 }, set_function: visca_set_zoom, get_function: visca_get_zoom, }, { property: { identifier: VISCA_ID_FOCUS, category: VISCA_CAT_LENS, unit: VISCA_UNIT_NONE, relations: 0, relations_count: 0, {value: VISCA_FOCUS_DEFAULT}, {range:{ VISCA_FOCUS_RANGE_MIN, VISCA_FOCUS_RANGE_MAX }}, stepping: 1.0f, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_AUTO, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: 0, property_data_size: 0 }, set_function: visca_set_focus, get_function: visca_get_focus, }, { property: { identifier: VISCA_ID_IRIS, category: VISCA_CAT_LENS, unit: VISCA_UNIT_NONE, relations: 0, relations_count: 0, {value: VISCA_IRIS_DEFAULT }, {range:{ VISCA_IRIS_RANGE_MIN, VISCA_IRIS_RANGE_MAX }}, stepping: 1.0f, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0 }, set_function: visca_set_focus, get_function: visca_get_focus, }, { property: { identifier: VISCA_ID_GAIN, category: VISCA_CAT_EXPOSURE, unit: VISCA_UNIT_NONE, relations: 0, relations_count: 0, {value: VISCA_GAIN_DEFAULT }, {range:{ VISCA_GAIN_RANGE_MIN, VISCA_GAIN_RANGE_MAX }}, stepping: 1.0f, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_AUTO, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: 0, property_data_size: 0 }, set_function: visca_set_gain, get_function: visca_get_gain, }, { property: { identifier: VISCA_ID_SHUTTER, category: VISCA_CAT_EXPOSURE, unit: VISCA_UNIT_NONE, relations: 0, relations_count: 0, {value: VISCA_SHUTTER_DEFAULT }, {range:{ VISCA_SHUTTER_RANGE_MIN, VISCA_SHUTTER_RANGE_MAX }}, stepping: 1.0f, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0 }, set_function: visca_set_shutter, get_function: visca_get_shutter, }, { property: { identifier: VISCA_ID_AUTOEXPOSURE_MODE, category: VISCA_CAT_EXPOSURE, unit: VISCA_UNIT_NONE, relations: 0, relations_count: 0, {menu_item:{ VISCA_AUTOEXPOSURE_MODE_DEFAULT}}, {menu:{ visca_autoexposure_mode_menu_items, sizeof( visca_autoexposure_mode_menu_items ) / sizeof ( char* ) } }, stepping: 0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, property_data_size: 0 }, set_function: visca_set_ae_mode, get_function: visca_get_ae_mode, }, }; #endif//__VISCA_PROPERTY_TABLE_H__ libunicap/cpi/vid21394/vid21394.h0000644000175000017500000000636313164711411016563 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __vid21394_h__ #define __vid21394_h__ #include #define VID21394_INVALID_HANDLE_VALUE 0 typedef struct vid21394_handle *vid21394handle_t; enum vid21394_frequency { VID21394_FREQ_50 = 0, VID21394_FREQ_60 = 1, VID21394_FREQ_AUTO = 3, VID21394_FREQ_UNKNOWN, }; enum vid21394_video_mode { VID21394_Y_320x240 = 0x4, VID21394_Y41P_320x240 = 0x6, VID21394_UYVY_320x240 = 0x1, VID21394_YUY2_320x240 = 0x101, VID21394_Y_640x480 = 0x5, VID21394_Y41P_640x480 = 0x2, VID21394_UYVY_640x480 = 0x3, VID21394_YUY2_640x480 = 0x103, VID21394_Y_768x576 = 0x7, VID21394_Y41P_768x576 = 0x8, VID21394_UYVY_768x576 = 0x9, VID21394_YUY2_768x576 = 0x109 }; enum vid21394_input_channel { VID21394_INPUT_COMPOSITE_1 = 0x4, VID21394_INPUT_COMPOSITE_2 = 0x5, VID21394_INPUT_COMPOSITE_3 = 0x1, VID21394_INPUT_COMPOSITE_4 = 0x3, VID21394_INPUT_SVIDEO = 0x9, VID21394_INPUT_AUTO = 0xff, }; /* Obtain a handle to a video 2 1394 device. Input: sernum: Serial number of device to open Output: handle to the device or NULL if the device could not be opened errno: ENOSYS: This kernel lacks raw1394 support EAGAIN: 1394 interface not accessible */ /* vid21394handle_t vid21394_open( unsigned long long sernum ); */ /* void vid21394_close( vid21394handle_t vid21394handle ); */ // converter operation /* int vid21394_start_transmit( vid21394handle_t vid21394handle ); */ /* int vid21394_stop_transmit( vid21394handle_t vid21394handle ); */ /* int vid21394_set_input_channel( vid21394handle_t handle, enum vid21394_input_channel channel ); */ /* int vid21394_set_brightness( vid21394handle_t vid21394handle, unsigned int brightness ); */ /* int vid21394_set_contrast( vid21394handle_t vid21394handle, unsigned int contrast ); */ /* int vid21394_set_frequency( vid21394handle_t vid21394handle, enum vid21394_frequency freq ); */ /* int vid21394_get_firm_vers( vid21394handle_t handle ); */ /* int vid21394_set_video_mode( vid21394handle_t vid21394handle, enum vid21394_video_mode video_mode ); */ /* int vid21394_start_receive( vid21394handle_t vid21394handle ); */ /* int vid21394_stop_receive( vid21394handle_t vid21394handle ); */ /* void vid21394_queue_buffer( vid21394handle_t vid21394handle, void * buffer ); */ /* void *vid21394_dequeue_buffer( vid21394handle_t vid21394handle ); */ /* int vid21394_wait_buffer( vid21394handle_t vid21394handle, void **buffer ); */ /* int vid21394_poll_buffer( vid21394handle_t vid21394handle ); */ #endif //__vid21394_h__ libunicap/cpi/vid21394/Fcp.h0000755000175000017500000000155213164711411016104 0ustar zmoelnigzmoelnig#ifndef __FCP_H__ #define __FCP_H__ #define FCP_COMMAND 0xE0313233 #define READ_I2C_BYTE_MSG 0x10 #define WRITE_I2C_BYTE_MSG 0x11 #define SET_VIDEO_MODE_MSG 0x12 #define GET_FIRM_VERS_MSG 0x13 #define INPUT_SELECT_MSG 0x14 #define CHK_VIDEO_LOCK_MSG 0x15 #define ENA_ISOCH_TX_MSG 0x16 #define AVSYNC_EVERY_HLINE_MSG 0x17 #define READ_LINK_REG_MSG 0x18 #define WRITE_LINK_REG_MSG 0x19 #define SERIAL_NUMBER_MSG 0x1A #define SET_VIDEO_FREQUENCY_MSG 0x1B #if EXPERIMENTAL_FW #define RS232_IO_MSG 0x1D #define RS232_CONFIG_MSG 0x1E #define LINK_SPEED_MSG 0x20 #endif #define ENTER_BOOTLOAD_MSG 0xB0 #define FCP_ACK_MSG 0xAA #define FCP_REJECTED_MSG 0xAF #define FCP_NOT_SUPP_MSG 0xE1 #endif//__FCP_H__ libunicap/cpi/vid21394/vid21394_base.h0000644000175000017500000001506213164711411017551 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMMANDS_H__ #define __COMMANDS_H__ #include #include "unicap.h" #include "unicap_cpi.h" #include "unicap_status.h" #ifdef RAW1394_1_1_API #include #endif #ifdef RAW1394_1_0_API #include #endif #include "vid21394.h" #include #include #include "queue.h" #define I2C_SAA7112_ID 0x420000 #define I2C_BRIGHTNESS 0xA00 #define I2C_CONTRAST 0xB00 #define I2C_SYNCCONTROL 0x800 #define I2C_BYTE_ORDER 0x8500 #define MAX_VID21394_HANDLES 16 #define FCP_TIMEOUT 5 #define EXPERIMENTAL_FW 1 union fcp_command { unsigned int int32value[2]; unsigned long long int64value; }; struct buffer_entry { unsigned char *data; struct buffer_entry *next; }; struct timeout_data { raw1394handle_t raw1394handle; volatile int capture_running; volatile int quit; }; typedef struct timeout_data timeout_data_t; struct parse_state { unicap_data_buffer_t *buffer; struct _unicap_queue *in_queue; struct _unicap_queue *out_queue; }; struct vid21394_handle { struct vid21394_handle *vid21394handle; raw1394handle_t raw1394handle; unicap_event_callback_t event_callback; unicap_handle_t unicap_handle; int node; int port; unsigned long long serial_number; int device_present; pthread_t timeout_thread; timeout_data_t timeout_data; int channel; // -1 when not transmitting int bandwidth; // 0 when not transmitting void * userdata; /* volatile unsigned long fcp_sync_bits; */ sem_t fcp_sync_sem[32]; int fcp_status[32]; unsigned int fcp_response[256]; int fcp_response_length; volatile unsigned int fcp_data; volatile unsigned int fcp_ext_data; volatile unsigned int firmware_version; enum vid21394_video_mode video_mode; unsigned long video_freq; struct _unicap_queue queued_buffers; struct _unicap_queue ready_buffers; struct _unicap_queue *current_data_buffer; struct parse_state parse_state; size_t raw_buffer_size; // size of a field buffer with isoch headers size_t dma_buffer_size; size_t dma_vmmap_frame_size; int dma_fd; int dma_capture_thread_quit; pthread_t dma_capture_thread; int current_offset; int current_field; int current_line_offset; int current_line_length; int current_buffer_size; int current_line_to_copy; int current_bytes_copied; int last_field_type; int copy_done; int start_copy; int copied_field_0; int copied_field_1; int num_buffers; int nr_pkts; int is_receiving; // set to 1 if isoch receive is active struct timeval filltime; int stop_capture; pthread_t capture_thread; unsigned char *system_buffer; struct _unicap_queue system_buffer_entry; unicap_format_t current_format; }; vid21394handle_t vid21394_open ( unsigned long long sernum ); void vid21394_close( vid21394handle_t vid21394handle ); int vid21394_start_transmit( vid21394handle_t vid21394handle ); int vid21394_stop_transmit( vid21394handle_t vid21394handle ); int vid21394_start_receive( vid21394handle_t vid21394handle ); int vid21394_stop_receive( vid21394handle_t vid21394handle ); void _vid21394_add_to_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ); unicap_status_t vid21394_set_input_channel( vid21394handle_t vid21394handle, enum vid21394_input_channel channel ); unicap_status_t vid21394_get_input_channel( vid21394handle_t vid21394handle, enum vid21394_input_channel *channel ); unicap_status_t vid21394_set_brightness ( vid21394handle_t vid21394handle, unsigned int brightness ); unicap_status_t vid21394_get_brightness ( vid21394handle_t vid21394handle, unsigned int *brightness ); unicap_status_t vid21394_set_frequency ( vid21394handle_t vid21394handle, enum vid21394_frequency freq ); unicap_status_t vid21394_get_frequency ( vid21394handle_t vid21394handle, enum vid21394_frequency *freq ); unicap_status_t vid21394_set_contrast ( vid21394handle_t vid21394handle, unsigned int contrast ); unicap_status_t vid21394_get_contrast ( vid21394handle_t vid21394handle, unsigned int *contrast ); unicap_status_t vid21394_set_force_odd_even( vid21394handle_t vid21394handle, unsigned int force ); unicap_status_t vid21394_get_force_odd_even( vid21394handle_t vid21394handle, unsigned int *force ); #if VID21394_BOOTLOAD unicap_status_t vid21394_enter_bootload( vid21394handle_t vid21394handle ); #endif unicap_status_t vid21394_write_rs232( vid21394handle_t vid21394handle, unsigned char *data, int datalen ); unicap_status_t vid21394_read_rs232 ( vid21394handle_t vid21394handle, unsigned char *data, int *datalen ); unicap_status_t vid21394_rs232_set_baudrate( vid21394handle_t vid21394handle, int rate ); unicap_status_t vid21394_rs232_io ( vid21394handle_t vid21394handle, unsigned char *out_data, int out_data_length, unsigned char *in_data, int in_data_length ); unicap_status_t vid21394_set_link_speed ( vid21394handle_t vid21394handle, int speed ); unicap_status_t vid21394_set_video_mode ( vid21394handle_t vid21394handle, enum vid21394_video_mode video_mode ); void * vid21394_capture_thread( vid21394handle_t vid21394handle ); void vid21394_queue_buffer( vid21394handle_t vid21394handle, void * buffer ); int vid21394_wait_buffer ( vid21394handle_t vid21394handle, void **buffer ); #endif //__COMMANDS_H__ libunicap/cpi/Makefile.am0000644000175000017500000000105513164711411016065 0ustar zmoelnigzmoelnig# process this file with automake to create a Makefile.in if BUILD_VID21394 DIR_VID21394 = vid21394 endif if BUILD_DCAM DIR_DCAM = dcam endif if BUILD_V4L DIR_V4L = v4l endif if BUILD_V4L2 DIR_V4L2 = v4l2cpi endif if BUILD_EUVCCAM DIR_EUVCCAM = euvccam endif if BUILD_ARAVIS DIR_ARAVIS = aravis endif if BUILD_THING DIR_THING = thing endif SUBDIRS = $(DIR_VID21394) $(DIR_DCAM) $(DIR_V4L) $(DIR_V4L2) $(DIR_EUVCCAM) $(DIR_ARAVIS) $(DIR_THING) DIST_SUBDIRS = vid21394 dcam v4l v4l2cpi euvccam aravis thing include MAINTAINERCLEANFILES = Makefile.in libunicap/cpi/aravis/0000755000175000017500000000000013164711411015315 5ustar zmoelnigzmoelniglibunicap/cpi/aravis/aravis_cpi.h0000644000175000017500000000304013164711411017603 0ustar zmoelnigzmoelnig/* unicap aravis plugin Copyright (C) 2011 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ARAVIS_CPI_H_ # define ARAVIS_CPI_H_ #include #include #include #include #include #include "aravis_properties.h" #include "queue.h" #include "debayer.h" #if ARAVIS_DEBUG #define DEBUG #endif #include "debug.h" #define MAX_FORMATS 12 struct aravis_handle { unsigned char type_flag; int removed; unicap_handle_t unicap_handle; unicap_event_callback_t event_callback; unicap_queue_t buffer_in_queue; unicap_queue_t buffer_out_queue; unicap_format_t current_format; unicap_format_t formats[MAX_FORMATS]; int n_formats; struct aravis_property *properties; int n_properties; ArvCamera *camera; ArvStream *stream; }; typedef struct aravis_handle *aravis_handle_t; #endif /* !ARAVIS_CPI_H_ */ libunicap/cpi/aravis/queue.c0000644000175000017500000001062713164711411016613 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #ifdef DEBUG #include #endif #include "queue.h" #include #include /* void _dump_queue( struct _unicap_queue *queue ) */ /* { */ /* int i = -1; */ /* printf( "## dump queue\n" ); */ /* while( queue->next ) */ /* { */ /* printf( "entry: %d, addr: %p\n", i++, queue ); */ /* printf( "entry->next: %p\n", queue->next ); */ /* printf( "data: %p\n", queue->data ); */ /* printf( "sema: %p\n", queue->psema ); */ /* queue = queue->next; */ /* } */ /* printf( "entry: %d, addr: %p\n", i, queue ); */ /* printf( "entry->next: %p\n", queue->next ); */ /* printf( "data: %p\n", queue->data ); */ /* printf( "sema: %p\n\n", queue->psema ); */ /* } */ void _insert_back_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { struct _unicap_queue *tmp_queue; if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } tmp_queue = queue; // run to the end of the queue while( tmp_queue->next ) { tmp_queue = tmp_queue->next; } tmp_queue->next = entry; entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); return; } } void _insert_front_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } entry->next = queue->next; entry->psema = queue->psema; queue->next = entry; if( sem_post( queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } struct _unicap_queue *_get_front_queue( struct _unicap_queue *queue ) { struct _unicap_queue *entry; if( sem_wait( queue->psema ) ) { TRACE( "sem_wait failed!\n" ); return 0; } if( !queue->next ) { entry = 0; sem_post( queue->psema ); goto out; } entry = queue->next; if( queue->next ) { queue->next = queue->next->next; } entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } out: return entry; } void _move_to_queue( struct _unicap_queue *from_queue, struct _unicap_queue *to_queue ) { struct _unicap_queue *tmp_to_queue; struct _unicap_queue *tmp_from_queue; struct _unicap_queue *entry; if( sem_wait( from_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( sem_wait( to_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( !from_queue->next ) { entry = 0; goto out; } tmp_from_queue = from_queue; /////////////////////////////////////////////////////////////// entry = from_queue->next; if( tmp_from_queue->next ) { tmp_from_queue->next = tmp_from_queue->next->next; } entry->next = 0; ////////////////////////////////////////////////////////////// tmp_to_queue = to_queue; // run to the end of the queue while( tmp_to_queue->next ) { tmp_to_queue = tmp_to_queue->next; } tmp_to_queue->next = entry; entry->psema = to_queue->psema; out: if( sem_post( from_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } if( sem_post( to_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } void _init_queue( struct _unicap_queue *queue ) { memset( queue, 0, sizeof( struct _unicap_queue ) ); if( sem_init( &queue->sema, 0, 1 ) ) { TRACE( "FATAL: sem_init failed\n" ); } queue->psema = &queue->sema; } int _queue_get_size( struct _unicap_queue *queue ) { int entries = 0; struct _unicap_queue *entry = queue; while( entry->next ) { entries++; entry = entry->next; } return entries; } void _destroy_queue( struct _unicap_queue *queue ) { sem_destroy( &queue->sema ); } libunicap/cpi/aravis/queue.h0000644000175000017500000000306613164711411016617 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __QUEUE_H__ #define __QUEUE_H__ #include #include struct _unicap_queue { sem_t sema; sem_t *psema; struct timeval fill_start_time; struct timeval fill_end_time; void * data; struct _unicap_queue *next; } unicap_queue; typedef struct _unicap_queue unicap_queue_t; void _init_queue( struct _unicap_queue *queue ); void _destroy_queue( struct _unicap_queue *queue ); void _insert_back_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ); void _insert_front_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ); struct _unicap_queue *_get_front_queue( struct _unicap_queue *queue ); void _move_to_queue( struct _unicap_queue *from_queue, struct _unicap_queue *to_queue ); int _queue_get_size( struct _unicap_queue *queue ); #endif//__QUEUE_H__ libunicap/cpi/aravis/Makefile.am0000644000175000017500000000115013164711411017346 0ustar zmoelnigzmoelnigINCLUDES = -I../include -I../../include -I../../ -I../../common if ENABLE_STATIC_CPI noinst_LTLIBRARIES=libaravis_cpi.la libaravis_cpi_la_LIBADD=-lpthread @ARAVIS_PACKAGE_LIBS@ else libcpi_LTLIBRARIES=libaravis_cpi.la libaravis_cpi_la_LIBADD=-lpthread @ARAVIS_PACKAGE_LIBS@ -L../../src/.libs/ -lunicap endif libcpidir = $(libdir)/unicap$(pkg_version)/cpi libaravis_cpi_la_CFLAGS=-O2 -g @ARAVIS_PACKAGE_CFLAGS@ libaravis_cpi_la_LDFLAGS=-module -avoid-version libaravis_cpi_la_SOURCES= \ aravis_cpi.c aravis_cpi.h \ aravis_tools.c aravis_tools.h \ aravis_properties.c aravis_properties.h \ logging.c logging.h libunicap/cpi/aravis/aravis_tools.h0000644000175000017500000000051513164711411020174 0ustar zmoelnigzmoelnig#ifndef __ARAVIS_TOOLS_H__ #define __ARAVIS_TOOLS_H__ unsigned int aravis_tools_get_fourcc (ArvPixelFormat fmt); const char *aravis_tools_get_pixel_format_string (ArvPixelFormat fmt); int aravis_tools_get_bpp (ArvPixelFormat fmt); ArvPixelFormat aravis_tools_get_pixel_format (unicap_format_t *format); #endif//__ARAVIS_TOOLS_H__ libunicap/cpi/aravis/aravis_properties.c0000644000175000017500000001123113164711411021220 0ustar zmoelnigzmoelnig#include #include #include #include "aravis_properties.h" #define N_(x) x #define N_ELEMENTS(a) (sizeof( a )/ sizeof(( a )[0] )) static unicap_status_t aravis_property_set_exposure(ArvCamera *cam, unicap_property_t *property); static unicap_status_t aravis_property_get_exposure(ArvCamera *cam, unicap_property_t *property); static unicap_status_t aravis_property_query_exposure(ArvCamera *cam, unicap_property_t *property); static unicap_status_t aravis_property_set_gain(ArvCamera *cam, unicap_property_t *property); static unicap_status_t aravis_property_get_gain(ArvCamera *cam, unicap_property_t *property); static unicap_status_t aravis_property_query_gain(ArvCamera *cam, unicap_property_t *property); static struct aravis_property aravis_properties[] = { { { identifier: N_("Shutter"), category: N_("Exposure"), unit: N_("s"), relations: NULL, relations_count: 0, {value: 0}, {range: {min: 0, max: 0}}, stepping: 0.0001, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, aravis_property_set_exposure, aravis_property_get_exposure, aravis_property_query_exposure }, { { identifier: N_("Gain"), category: N_("Exposure"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: {min: 0, max: 0}}, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, aravis_property_set_gain, aravis_property_get_gain, aravis_property_query_gain }, }; static unicap_status_t aravis_property_set_exposure(ArvCamera *cam, unicap_property_t *property) { if (property->flags & UNICAP_FLAGS_ONE_PUSH){ arv_camera_set_exposure_time_auto (cam, ARV_AUTO_ONCE); } else if (property->flags & UNICAP_FLAGS_AUTO){ arv_camera_set_exposure_time_auto (cam, ARV_AUTO_CONTINUOUS); } else { arv_camera_set_exposure_time_auto (cam, ARV_AUTO_OFF); arv_camera_set_exposure_time (cam, property->value * 1000000.0); } return STATUS_SUCCESS; } static unicap_status_t aravis_property_get_exposure(ArvCamera *cam, unicap_property_t *property) { switch (arv_camera_get_exposure_time_auto (cam)){ default: case ARV_AUTO_OFF: property->flags = UNICAP_FLAGS_MANUAL; break; case ARV_AUTO_ONCE: property->flags = UNICAP_FLAGS_ONE_PUSH; break; case ARV_AUTO_CONTINUOUS: property->flags = UNICAP_FLAGS_AUTO; break; } property->value = arv_camera_get_exposure_time (cam) / 1000000.0; return STATUS_SUCCESS; } static unicap_status_t aravis_property_query_exposure(ArvCamera *cam, unicap_property_t *property) { arv_camera_get_exposure_time_bounds (cam, &property->range.min, &property->range.max); property->range.min /= 1000000.0; property->range.max /= 1000000.0; aravis_property_get_exposure (cam, property); return STATUS_SUCCESS; } static unicap_status_t aravis_property_set_gain(ArvCamera *cam, unicap_property_t *property) { if (property->flags & UNICAP_FLAGS_ONE_PUSH){ arv_camera_set_gain_auto (cam, ARV_AUTO_ONCE); } else if (property->flags & UNICAP_FLAGS_AUTO){ arv_camera_set_gain_auto (cam, ARV_AUTO_CONTINUOUS); } else { arv_camera_set_gain_auto (cam, ARV_AUTO_OFF); arv_camera_set_gain (cam, property->value); } return STATUS_SUCCESS; } static unicap_status_t aravis_property_get_gain(ArvCamera *cam, unicap_property_t *property) { switch (arv_camera_get_gain_auto (cam)){ default: case ARV_AUTO_OFF: property->flags = UNICAP_FLAGS_MANUAL; break; case ARV_AUTO_ONCE: property->flags = UNICAP_FLAGS_ONE_PUSH; break; case ARV_AUTO_CONTINUOUS: property->flags = UNICAP_FLAGS_AUTO; break; } property->value = arv_camera_get_gain (cam); return STATUS_SUCCESS; } static unicap_status_t aravis_property_query_gain(ArvCamera *cam, unicap_property_t *property) { gint min,max; arv_camera_get_gain_bounds (cam, &min, &max); property->range.min = min; property->range.max = max; aravis_property_get_gain (cam, property); return STATUS_SUCCESS; } void aravis_properties_create_table(ArvCamera *cam, struct aravis_property **properties, unsigned int *n_properties) { int i; int cnt = 0; struct aravis_property *propt = NULL; propt = malloc(sizeof(struct aravis_property) * N_ELEMENTS(aravis_properties)); for (i=0; i < N_ELEMENTS(aravis_properties); i++){ memcpy (propt + cnt, aravis_properties + i, sizeof (struct aravis_property)); if(SUCCESS( propt[cnt].query(cam, &propt[cnt].property) )) cnt++; } *n_properties = cnt; *properties = propt; } libunicap/cpi/aravis/aravis_properties.h0000644000175000017500000000074413164711411021234 0ustar zmoelnigzmoelnig#ifndef __ARAVIS_PROPERTIES_H__ #define __ARAVIS_PROPERTIES_H__ #include typedef unicap_status_t(*aravis_property_func_t)(ArvCamera *camera, unicap_property_t *property); struct aravis_property { unicap_property_t property; aravis_property_func_t set; aravis_property_func_t get; aravis_property_func_t query; }; void aravis_properties_create_table(ArvCamera *cam, struct aravis_property **properties, unsigned int *n_properties); #endif//__ARAVIS_PROPERTIES_H__ libunicap/cpi/aravis/logging.h0000644000175000017500000000205113164711411017112 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LOGGING__ #define __LOGGING__ #define LOG_MODULE_CAPTURE 2 #define LOG_MODULE_USB 3 #define LOG_MODULE_DEVICE 4 #define LOG_MODULE_ANY 1 void log_init( void ); void log_close( void ); void log_message( int module, int log_level, const char *format, ... ); #endif//__LOGGING__ libunicap/cpi/aravis/logging.c0000644000175000017500000000337113164711411017113 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include FILE *g_logfp = NULL; int g_log_modules_mask = 0xffff; int g_log_level = 0; void log_init( void ) { char *tmp = getenv( "UNICAP_EUVCCAM_LOG_PATH" ); if( tmp ) g_logfp = fopen( tmp, "w" ); tmp = getenv( "UNICAP_EUVCCAM_LOG_LEVEL" ); if( tmp ) g_log_level = atoi( tmp ); tmp = getenv( "UNICAP_EUVCCAM_LOG_MODULES_MASK" ); if( tmp ) g_log_modules_mask = atoi( tmp ); } void log_close( void ) { if( g_logfp ) fclose( g_logfp ); g_logfp = NULL; } void log_message( int module, int log_level, const char *format, ... ) { if( ( module & g_log_modules_mask ) && ( log_level > g_log_level ) ){ char message[ 128 ]; va_list ap; va_start( ap, format ); vsnprintf( message, sizeof( message ), format, ap ); va_end( ap ); if( g_logfp ){ fwrite( message, strlen( message ), 1, g_logfp ); fflush( g_logfp ); }else{ printf( "%s", message ); } } } libunicap/cpi/aravis/aravis_tools.c0000644000175000017500000001013013164711411020161 0ustar zmoelnigzmoelnig#include #include #define N_ELEMENTS(a) (sizeof( a )/ sizeof(( a )[0] )) #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) struct aravis_pixel_format { ArvPixelFormat pixel_format; unsigned int fourcc; int bpp; char *desc; }; static struct aravis_pixel_format pixel_fmt_desc[] = { /* Grey pixel formats */ { ARV_PIXEL_FORMAT_MONO_8, FOURCC ('Y', '8', '0', '0'), 8, "Y800" }, { ARV_PIXEL_FORMAT_MONO_8_SIGNED, FOURCC ('S', 'Y', '8', 0), 8, "Signed Mono8" }, { ARV_PIXEL_FORMAT_MONO_10, FOURCC ('Y', '1', '0', 0), 10, "Mono10" }, { ARV_PIXEL_FORMAT_MONO_10_PACKED, FOURCC ('Y', '1', '0', 'P'), 10, "Mono10 packed" }, { ARV_PIXEL_FORMAT_MONO_12, FOURCC ('Y', '1', '2', 0), 12, "Mono12" }, { ARV_PIXEL_FORMAT_MONO_12_PACKED, FOURCC ('Y', '1', '2', 'P'), 12, "Mono12 packed" }, { ARV_PIXEL_FORMAT_MONO_16, FOURCC ('Y', '1', '6', 0), 16, "Mono16" }, /* { */ /* ARV_PIXEL_FORMAT_BAYER_GR_8, */ /* FOURCC ('B', 'Y', '8', 0), */ /* "Bayer GR 8", */ /* ARV_PIXEL_FORMAT_BAYER_RG_8 = 0x01080009, */ /* ARV_PIXEL_FORMAT_BAYER_GB_8 = 0x0108000a, */ /* ARV_PIXEL_FORMAT_BAYER_BG_8 = 0x0108000b, */ /* ARV_PIXEL_FORMAT_BAYER_GR_10 = 0x0110000c, */ /* ARV_PIXEL_FORMAT_BAYER_RG_10 = 0x0110000d, */ /* ARV_PIXEL_FORMAT_BAYER_GB_10 = 0x0110000e, */ /* ARV_PIXEL_FORMAT_BAYER_BG_10 = 0x0110000f, */ /* ARV_PIXEL_FORMAT_BAYER_GR_12 = 0x01100010, */ /* ARV_PIXEL_FORMAT_BAYER_RG_12 = 0x01100011, */ /* ARV_PIXEL_FORMAT_BAYER_GB_12 = 0x01100012, */ /* ARV_PIXEL_FORMAT_BAYER_BG_12 = 0x01100013, */ /* /\* Color pixel formats *\/ */ /* ARV_PIXEL_FORMAT_RGB_8_PACKED = 0x02180014, */ /* ARV_PIXEL_FORMAT_BGR_8_PACKED = 0x02180015, */ /* ARV_PIXEL_FORMAT_RGBA_8_PACKED = 0x02200016, */ /* ARV_PIXEL_FORMAT_BGRA_8_PACKED = 0x02200017, */ /* ARV_PIXEL_FORMAT_RGB_10_PACKED = 0x02300018, */ /* ARV_PIXEL_FORMAT_BGR_10_PACKED = 0x02300019, */ /* ARV_PIXEL_FORMAT_RGB_12_PACKED = 0x0230001a, */ /* ARV_PIXEL_FORMAT_BGR_12_PACKED = 0x0230001b, */ /* ARV_PIXEL_FORMAT_YUV_411_PACKED = 0x020c001e, */ /* ARV_PIXEL_FORMAT_YUV_422_PACKED = 0x0210001f, */ /* ARV_PIXEL_FORMAT_YUV_444_PACKED = 0x02180020, */ /* ARV_PIXEL_FORMAT_RGB_8_PLANAR = 0x02180021, */ /* ARV_PIXEL_FORMAT_RGB_10_PLANAR = 0x02300022, */ /* ARV_PIXEL_FORMAT_RGB_12_PLANAR = 0x02300023, */ /* ARV_PIXEL_FORMAT_RGB_16_PLANAR = 0x02300024, */ /* ARV_PIXEL_FORMAT_YUV_422_YUYV_PACKED = 0x02100032, */ /* /\* Custom *\/ */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_GR_12_PACKED = 0x810c0001, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_RG_12_PACKED = 0x810c0002, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_GB_12_PACKED = 0x810c0003, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_BG_12_PACKED = 0x810c0004, */ /* ARV_PIXEL_FORMAT_CUSTOM_YUV_422_YUYV_PACKED = 0x82100005, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_GR_16 = 0x81100006, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_RG_16 = 0x81100007, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_GB_16 = 0x81100008, */ /* ARV_PIXEL_FORMAT_CUSTOM_BAYER_BG_16 = 0x81100009 */ }; unsigned int aravis_tools_get_fourcc (ArvPixelFormat fmt) { int i; for (i = 0; i < N_ELEMENTS (pixel_fmt_desc); i++){ if (pixel_fmt_desc [i].pixel_format == fmt) return pixel_fmt_desc [i].fourcc; } return 0; } const char *aravis_tools_get_pixel_format_string (ArvPixelFormat fmt) { int i; for (i = 0; i < N_ELEMENTS (pixel_fmt_desc); i++){ if (pixel_fmt_desc [i].pixel_format == fmt) return pixel_fmt_desc [i].desc; } return "Unknown"; } int aravis_tools_get_bpp (ArvPixelFormat fmt) { int i; for (i = 0; i < N_ELEMENTS (pixel_fmt_desc); i++){ if (pixel_fmt_desc [i].pixel_format == fmt) return pixel_fmt_desc [i].bpp; } return 0; } ArvPixelFormat aravis_tools_get_pixel_format (unicap_format_t *format) { ArvPixelFormat ret = 0; int i; for (i = 0; i < N_ELEMENTS (pixel_fmt_desc); i++){ if ((pixel_fmt_desc[i].fourcc == format->fourcc) || (!strcmp (pixel_fmt_desc [i].desc, format->identifier))){ ret = pixel_fmt_desc [i].pixel_format; break; } } return ret; } libunicap/cpi/aravis/aravis_cpi.c0000644000175000017500000003151613164711411017607 0ustar zmoelnigzmoelnig/* unicap aravis plugin Copyright (C) 2011 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "aravis_cpi.h" #include "aravis_tools.h" #include "unicap_cpi.h" #include "queue.h" #include "logging.h" static unicap_status_t aravis_enumerate_devices( unicap_device_t *device, int index ); static unicap_status_t aravis_open( void **cpi_data, unicap_device_t *device ); static unicap_status_t aravis_close( aravis_handle_t handle ); static unicap_status_t aravis_reenumerate_formats( aravis_handle_t handle, int *_pcount ); static unicap_status_t aravis_enumerate_formats( aravis_handle_t handle, unicap_format_t *format, int index ); static unicap_status_t aravis_set_format( aravis_handle_t handle, unicap_format_t *format ); static unicap_status_t aravis_get_format( aravis_handle_t handle, unicap_format_t *format ); static unicap_status_t aravis_reenumerate_properties( aravis_handle_t handle, int *_pcount ); static unicap_status_t aravis_enumerate_properties( aravis_handle_t handle, unicap_property_t *property, int index ); static unicap_status_t aravis_set_property( aravis_handle_t handle, unicap_property_t *property ); static unicap_status_t aravis_get_property( aravis_handle_t handle, unicap_property_t *property ); static unicap_status_t aravis_capture_start( aravis_handle_t handle ); static unicap_status_t aravis_capture_stop( aravis_handle_t handle ); static unicap_status_t aravis_queue_buffer( aravis_handle_t handle, unicap_data_buffer_t *buffer ); static unicap_status_t aravis_dequeue_buffer( aravis_handle_t handle, unicap_data_buffer_t **buffer ); static unicap_status_t aravis_wait_buffer( aravis_handle_t handle, unicap_data_buffer_t **buffer ); static unicap_status_t aravis_poll_buffer( aravis_handle_t handle, int *count ); static unicap_status_t aravis_set_event_notify( aravis_handle_t handle, unicap_event_callback_t func, unicap_handle_t unicap_handle ); static void aravis_stream_callback( aravis_handle_t handle, ArvStreamCallbackType type, ArvBuffer *buffer); static struct _unicap_cpi cpi_s = { cpi_version: 1<<16, cpi_capabilities: 0x3ffff, cpi_flags: UNICAP_CPI_SERIALIZED, cpi_enumerate_devices: aravis_enumerate_devices, cpi_open: (cpi_open_t)aravis_open, cpi_close: (cpi_close_t)aravis_close, cpi_reenumerate_formats: (cpi_reenumerate_formats_t)aravis_reenumerate_formats, cpi_enumerate_formats: (cpi_enumerate_formats_t)aravis_enumerate_formats, cpi_set_format: (cpi_set_format_t)aravis_set_format, cpi_get_format: (cpi_get_format_t)aravis_get_format, cpi_reenumerate_properties: (cpi_reenumerate_properties_t)aravis_reenumerate_properties, cpi_enumerate_properties: (cpi_enumerate_properties_t)aravis_enumerate_properties, cpi_set_property: (cpi_set_property_t)aravis_set_property, cpi_get_property: (cpi_get_property_t)aravis_get_property, cpi_capture_start: (cpi_capture_start_t)aravis_capture_start, cpi_capture_stop: (cpi_capture_stop_t)aravis_capture_stop, cpi_queue_buffer: (cpi_queue_buffer_t)aravis_queue_buffer, cpi_dequeue_buffer: (cpi_dequeue_buffer_t)aravis_dequeue_buffer, cpi_wait_buffer: (cpi_wait_buffer_t)aravis_wait_buffer, cpi_poll_buffer: (cpi_poll_buffer_t)aravis_poll_buffer, cpi_set_event_notify: (cpi_set_event_notify_t)aravis_set_event_notify, }; static int is_initialized = 0; unicap_status_t cpi_register (struct _unicap_cpi *reg_data) { memcpy (reg_data, &cpi_s, sizeof( struct _unicap_cpi )); if (!is_initialized){ is_initialized = 1; log_init(); g_thread_init (NULL); g_type_init (); arv_debug_enable ("device,misc"); } return STATUS_SUCCESS; } static unicap_status_t aravis_enumerate_devices (unicap_device_t *device, int index) { unicap_status_t status = STATUS_NO_MATCH; if (index == 0) arv_update_device_list (); unicap_void_device (device); if (index < arv_get_n_devices ()){ ArvCamera *camera; strncpy (device->identifier, arv_get_device_id (index), sizeof (device->identifier)-1); camera = arv_camera_new (device->identifier); if (arv_camera_get_model_name (camera)) strncpy (device->model_name, arv_camera_get_model_name (camera), sizeof (device->model_name)-1); if (arv_camera_get_vendor_name (camera)) strncpy (device->vendor_name, arv_camera_get_vendor_name (camera), sizeof (device->vendor_name)-1); strcpy (device->cpi_layer, "aravis_cpi"); status = STATUS_SUCCESS; g_object_unref (camera); } return status; } static unicap_status_t aravis_open( void **cpi_data, unicap_device_t *device ) { unicap_status_t status = STATUS_SUCCESS; aravis_handle_t handle; int i; handle = malloc (sizeof (struct aravis_handle)); if( !handle ) return STATUS_FAILURE; memset( handle, 0x0, sizeof( struct aravis_handle ) ); *cpi_data = handle; handle->camera = arv_camera_new (device->identifier); if (!handle->camera) goto err; aravis_reenumerate_formats (handle, NULL); aravis_get_format( handle, &handle->current_format ); aravis_properties_create_table (handle->camera, &handle->properties, &handle->n_properties); /* _init_queue( &handle->buffer_in_queue ); */ /* _init_queue( &handle->buffer_out_queue ); */ return status; err: free( handle ); return status; } static unicap_status_t aravis_close( aravis_handle_t handle ) { free( handle ); return STATUS_SUCCESS; } static unicap_status_t aravis_reenumerate_formats( aravis_handle_t handle, int *_pcount ) { int idx = 0; int i; guint n_pixel_formats; gint64 *pixel_formats; int min_width, max_width; int min_height, max_height; pixel_formats = arv_camera_get_available_pixel_formats (handle->camera, &n_pixel_formats); arv_camera_get_width_bounds (handle->camera, &min_width, &max_width); arv_camera_get_height_bounds (handle->camera, &min_height, &max_height); for (i = 0; i < n_pixel_formats; i++){ unsigned int fourcc; fourcc = aravis_tools_get_fourcc (pixel_formats[i]); if (fourcc){ unicap_void_format (&handle->formats[idx]); handle->formats[idx].fourcc = fourcc; strcpy (handle->formats[idx].identifier, aravis_tools_get_pixel_format_string (pixel_formats[i])); handle->formats[idx].bpp = aravis_tools_get_bpp (pixel_formats[i]); handle->formats[idx].min_size.width = min_width; handle->formats[idx].min_size.height = min_height; handle->formats[idx].max_size.width = max_width; handle->formats[idx].max_size.height = max_height; handle->formats[idx].size.width = max_width; handle->formats[idx].size.height = max_height; handle->formats[idx].buffer_size = max_width * max_height * handle->formats[idx].bpp / 8; handle->formats[idx].buffer_type = UNICAP_BUFFER_TYPE_SYSTEM; idx++; } } g_free (pixel_formats); handle->n_formats = idx; if( _pcount ) *_pcount = handle->n_formats; return STATUS_SUCCESS; } static unicap_status_t aravis_enumerate_formats( aravis_handle_t handle, unicap_format_t *format, int index ) { unicap_status_t status = STATUS_NO_MATCH; if ((index >= 0) && (index < handle->n_formats)){ unicap_copy_format (format, &handle->formats[index]); status = STATUS_SUCCESS; } return status; } static unicap_status_t aravis_set_format( aravis_handle_t handle, unicap_format_t *format ) { ArvPixelFormat fmt = aravis_tools_get_pixel_format (format); if (fmt == 0) return STATUS_INVALID_PARAMETER; arv_camera_set_pixel_format (handle->camera, fmt); arv_camera_set_region (handle->camera, format->size.x, format->size.y, format->size.width, format->size.height); unicap_copy_format (&handle->current_format, format); return STATUS_SUCCESS; } static unicap_status_t aravis_get_format( aravis_handle_t handle, unicap_format_t *format ) { ArvPixelFormat pixel_fmt = arv_camera_get_pixel_format (handle->camera); if (!pixel_fmt) return STATUS_FAILURE; unicap_void_format (format); strcpy (format->identifier, aravis_tools_get_pixel_format_string (pixel_fmt)); format->fourcc = aravis_tools_get_fourcc (pixel_fmt); format->bpp = aravis_tools_get_bpp (pixel_fmt); arv_camera_get_region (handle->camera, &format->size.x, &format->size.y, &format->size.width, &format->size.height); arv_camera_get_width_bounds (handle->camera, &format->min_size.width, &format->max_size.width); arv_camera_get_height_bounds (handle->camera, &format->min_size.height, &format->max_size.height); format->buffer_size = format->bpp * format->size.width * format->size.height / 8; format->buffer_type = UNICAP_BUFFER_TYPE_SYSTEM; return STATUS_SUCCESS; } static unicap_status_t aravis_reenumerate_properties( aravis_handle_t handle, int *_pcount ) { int count = 0; if( _pcount ){ *_pcount = handle->n_properties; } return STATUS_SUCCESS; } static unicap_status_t aravis_enumerate_properties( aravis_handle_t handle, unicap_property_t *property, int index ) { unicap_status_t status = STATUS_NO_MATCH; if ((index) >= 0 && (index < handle->n_properties)){ unicap_copy_property (property, &handle->properties[index].property); status = STATUS_SUCCESS; } return status; } static unicap_status_t aravis_set_property( aravis_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; int i; for (i=0; i < handle->n_properties; i++){ if (!strncmp (handle->properties[i].property.identifier, property->identifier, sizeof (property->identifier))){ status = handle->properties[i].set (handle->camera, property); } } return status; } static unicap_status_t aravis_get_property( aravis_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; int i; for (i=0; i < handle->n_properties; i++){ if (!strncmp (handle->properties[i].property.identifier, property->identifier, sizeof (property->identifier))){ unicap_copy_property (property, &handle->properties[i].property); status = handle->properties[i].get (handle->camera, property); } } return status; } static unicap_status_t aravis_capture_start( aravis_handle_t handle ) { guint payload; int i; handle->stream = arv_camera_create_stream( handle->camera, aravis_stream_callback, handle); arv_camera_set_acquisition_mode (handle->camera, ARV_ACQUISITION_MODE_CONTINUOUS); arv_camera_start_acquisition (handle->camera); payload = arv_camera_get_payload (handle->camera); for (i=0; i < 8; i++) arv_stream_push_buffer (handle->stream, arv_buffer_new (payload, NULL)); return handle->stream ? STATUS_SUCCESS : STATUS_FAILURE; } static unicap_status_t aravis_capture_stop( aravis_handle_t handle ) { arv_camera_stop_acquisition (handle->camera); if (handle->stream){ g_object_unref (handle->stream); handle->stream = NULL; } return STATUS_SUCCESS; } static unicap_status_t aravis_queue_buffer( aravis_handle_t handle, unicap_data_buffer_t *buffer ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t aravis_dequeue_buffer( aravis_handle_t handle, unicap_data_buffer_t **buffer ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t aravis_wait_buffer( aravis_handle_t handle, unicap_data_buffer_t **buffer ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t aravis_poll_buffer( aravis_handle_t handle, int *count ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t aravis_set_event_notify( aravis_handle_t handle, unicap_event_callback_t func, unicap_handle_t unicap_handle ) { handle->event_callback = func; handle->unicap_handle = unicap_handle; return STATUS_SUCCESS; } static void aravis_stream_callback( aravis_handle_t handle, ArvStreamCallbackType type, ArvBuffer *buffer) { if (type == ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE){ unicap_data_buffer_t data_buffer; unicap_copy_format (&data_buffer.format, &handle->current_format); data_buffer.buffer_size = buffer->size; data_buffer.data = buffer->data; data_buffer.type = UNICAP_BUFFER_TYPE_SYSTEM; data_buffer.fill_time.tv_sec = buffer->timestamp_ns / 1000000000ULL; data_buffer.fill_time.tv_usec = (buffer->timestamp_ns % 1000000000ULL) / 1000ULL; handle->event_callback (handle->unicap_handle, UNICAP_EVENT_NEW_FRAME, &data_buffer); arv_stream_push_buffer (handle->stream, buffer); } } libunicap/cpi/euvccam/0000755000175000017500000000000013164711411015453 5ustar zmoelnigzmoelniglibunicap/cpi/euvccam/euvccam_colorproc.h0000644000175000017500000000334413164711411021335 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __EUVCCAM_COLORPROC_H__ #define __EUVCCAM_COLORPROC_H__ #include "euvccam_cpi.h" void euvccam_colorproc_by8_rgb24_nn( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ); void euvccam_colorproc_by8_rgb24_nn_be( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ); void euvccam_colorproc_by8_gr_rgb24_nn( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ); void euvccam_colorproc_auto_wb( euvccam_handle_t handle, unicap_data_buffer_t *buffer ); unicap_status_t euvccam_colorproc_set_wbgain( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_colorproc_get_wbgain( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_colorproc_set_wbgain_mode( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_colorproc_get_wbgain_mode( euvccam_handle_t handle, unicap_property_t *property ); #endif//__EUVCCAM_COLORPROC_H__ libunicap/cpi/euvccam/queue.c0000644000175000017500000001062713164711411016751 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #ifdef DEBUG #include #endif #include "queue.h" #include #include /* void _dump_queue( struct _unicap_queue *queue ) */ /* { */ /* int i = -1; */ /* printf( "## dump queue\n" ); */ /* while( queue->next ) */ /* { */ /* printf( "entry: %d, addr: %p\n", i++, queue ); */ /* printf( "entry->next: %p\n", queue->next ); */ /* printf( "data: %p\n", queue->data ); */ /* printf( "sema: %p\n", queue->psema ); */ /* queue = queue->next; */ /* } */ /* printf( "entry: %d, addr: %p\n", i, queue ); */ /* printf( "entry->next: %p\n", queue->next ); */ /* printf( "data: %p\n", queue->data ); */ /* printf( "sema: %p\n\n", queue->psema ); */ /* } */ void _insert_back_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { struct _unicap_queue *tmp_queue; if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } tmp_queue = queue; // run to the end of the queue while( tmp_queue->next ) { tmp_queue = tmp_queue->next; } tmp_queue->next = entry; entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); return; } } void _insert_front_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } entry->next = queue->next; entry->psema = queue->psema; queue->next = entry; if( sem_post( queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } struct _unicap_queue *_get_front_queue( struct _unicap_queue *queue ) { struct _unicap_queue *entry; if( sem_wait( queue->psema ) ) { TRACE( "sem_wait failed!\n" ); return 0; } if( !queue->next ) { entry = 0; sem_post( queue->psema ); goto out; } entry = queue->next; if( queue->next ) { queue->next = queue->next->next; } entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } out: return entry; } void _move_to_queue( struct _unicap_queue *from_queue, struct _unicap_queue *to_queue ) { struct _unicap_queue *tmp_to_queue; struct _unicap_queue *tmp_from_queue; struct _unicap_queue *entry; if( sem_wait( from_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( sem_wait( to_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( !from_queue->next ) { entry = 0; goto out; } tmp_from_queue = from_queue; /////////////////////////////////////////////////////////////// entry = from_queue->next; if( tmp_from_queue->next ) { tmp_from_queue->next = tmp_from_queue->next->next; } entry->next = 0; ////////////////////////////////////////////////////////////// tmp_to_queue = to_queue; // run to the end of the queue while( tmp_to_queue->next ) { tmp_to_queue = tmp_to_queue->next; } tmp_to_queue->next = entry; entry->psema = to_queue->psema; out: if( sem_post( from_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } if( sem_post( to_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } void _init_queue( struct _unicap_queue *queue ) { memset( queue, 0, sizeof( struct _unicap_queue ) ); if( sem_init( &queue->sema, 0, 1 ) ) { TRACE( "FATAL: sem_init failed\n" ); } queue->psema = &queue->sema; } int _queue_get_size( struct _unicap_queue *queue ) { int entries = 0; struct _unicap_queue *entry = queue; while( entry->next ) { entries++; entry = entry->next; } return entries; } void _destroy_queue( struct _unicap_queue *queue ) { sem_destroy( &queue->sema ); } libunicap/cpi/euvccam/queue.h0000644000175000017500000000306613164711411016755 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __QUEUE_H__ #define __QUEUE_H__ #include #include struct _unicap_queue { sem_t sema; sem_t *psema; struct timeval fill_start_time; struct timeval fill_end_time; void * data; struct _unicap_queue *next; } unicap_queue; typedef struct _unicap_queue unicap_queue_t; void _init_queue( struct _unicap_queue *queue ); void _destroy_queue( struct _unicap_queue *queue ); void _insert_back_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ); void _insert_front_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ); struct _unicap_queue *_get_front_queue( struct _unicap_queue *queue ); void _move_to_queue( struct _unicap_queue *from_queue, struct _unicap_queue *to_queue ); int _queue_get_size( struct _unicap_queue *queue ); #endif//__QUEUE_H__ libunicap/cpi/euvccam/debayer.c0000644000175000017500000004711713164711411017244 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #ifdef __SSE2__ #include #endif #include "debayer.h" union _rgb24pixel { struct { unsigned char r; unsigned char g; unsigned char b; }c; unsigned int combined:24; }__attribute__((packed)); typedef union _rgb24pixel rgb24pixel_t; #define YUV_Y(r,g,b) ( ( ( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16 ) #define YUV_U(r,g,b) ( ( ( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128 ) #define YUV_V(r,g,b) ( ( ( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128 ) #define CRR(x) (x[0][0]) #define CRG(x) (x[0][1]) #define CRB(x) (x[0][2]) #define CGR(x) (x[1][0]) #define CGG(x) (x[1][1]) #define CGB(x) (x[1][2]) #define CBR(x) (x[2][0]) #define CBG(x) (x[2][1]) #define CBB(x) (x[2][2]) #define CLIP(x) (x>255?255:x<0?0:x) #define ABS(x) ((x)<0?(-1*x):(x)) void debayer_calculate_rbgain( unicap_data_buffer_t *buffer, int *rgain, int *bgain, int *combined ) { int x,y; int stepx, stepy; int rval = 0, gval = 0, bval = 0; stepx = ( buffer->format.size.width / 64 ) & ~1; stepy = ( buffer->format.size.height / 64 ) & ~1; for( y = 0; y < buffer->format.size.height; y += stepy ) { for( x = 0; x < buffer->format.size.width; x+= stepx ) { gval += buffer->data[ y * buffer->format.size.width + x ]; bval += buffer->data[ y * buffer->format.size.width + x + 1 ]; rval += buffer->data[ (y+1) * buffer->format.size.width + x ]; } } *rgain = (int)( ((double)gval * 4096.0) / (double)rval ); *bgain = (int)( ((double)gval * 4096.0) / (double)bval ); *combined = rval + gval + bval; } void debayer_ccm_rgb24_nn( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ) { int i, j; int dest_offset = 0; unsigned char *dest = destbuf->data; unsigned char *source = srcbuf->data; int width = srcbuf->format.size.width; int height = srcbuf->format.size.height; int rgain, bgain; if( data->use_rbgain ) { rgain = data->rgain; bgain = data->bgain; } else { rgain = 4096; bgain = 4096; } for( j = 1; j < height-1; j+=2 ) { int lineoffset = j*width; //RGRGR //GBGBG //RGRGR for( i = 0; i < width -1; ) { *dest++ = CLIP(( (unsigned int)source[ lineoffset + i ] * rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width ] + (unsigned int)source[ lineoffset + i + 1]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width + 1] * bgain ) / 4096); i++; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + 1 ] *rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width + 1 ] + (int)source[ lineoffset + i ]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width ] * bgain ) / 4096); i++; } lineoffset = (j+1)*width; //GBGBG //RGRGR //GBGBG for( i = 0; i < width -1; ) { *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width ] * rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width + 1 ] + (int)source[ lineoffset + i ]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + 1 ] * bgain ) / 4096); i++; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width + 1 ] * rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width ] + (int)source[ lineoffset + i + 1 ]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i ] * bgain ) / 4096); i++; } } } void debayer_ccm_rgb24_nn_be( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ) { int i, j; int dest_offset = 0; unsigned char *dest = destbuf->data; unsigned char *source = srcbuf->data; int width = srcbuf->format.size.width; int height = srcbuf->format.size.height; int rgain, bgain; static int odd = 0; if( data->use_rbgain ) { rgain = data->rgain; bgain = data->bgain; } else { rgain = 4096; bgain = 4096; } /* if( !odd ){ */ /* for( i = 0; i < ( width* height ) - 2; i+=2 ){ */ /* *(unsigned short *)(source+i) = ntohs( *(unsigned short *)(source+i) ); */ /* } */ /* odd = 1; */ /* printf( "odd\n" ); */ /* }else{ */ /* odd = 0; */ /* } */ for( j = 1; j < height-1; j+=2 ) { int lineoffset = j*width; //RGRGR //GBGBG //RGRGR for( i = 0; i < width -1; ) { *dest++ = CLIP(( (unsigned int)source[ lineoffset + i ] * rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width ] + (unsigned int)source[ lineoffset + i + 1]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width + 1] * bgain ) / 4096); i++; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + 1 ] *rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width + 1 ] + (int)source[ lineoffset + i ]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width ] * bgain ) / 4096); i++; } lineoffset = (j+1)*width; //GBGBG //RGRGR //GBGBG for( i = 0; i < width -1; ) { *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width ] * rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width + 1 ] + (int)source[ lineoffset + i ]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + 1 ] * bgain ) / 4096); i++; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i + width + 1 ] * rgain ) / 4096); *dest++ = ( (unsigned int)source[ lineoffset + i + width ] + (int)source[ lineoffset + i + 1 ]) / 2; *dest++ = CLIP(( (unsigned int)source[ lineoffset + i ] * bgain ) / 4096); i++; } } } void debayer_ccm_rgb24_gr_nn( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ) { int i, j; int dest_offset = 0; unsigned char *dest = destbuf->data; unsigned char *source = srcbuf->data; int width = srcbuf->format.size.width; int height = srcbuf->format.size.height; int rgain, bgain; if( data->use_rbgain ) { rgain = data->rgain; bgain = data->bgain; } else { rgain = 4096; bgain = 4096; } for( j = 1; j < height-1; j+=2 ) { int lineoffset = j*width; //RGRGR //GBGBG //RGRGR for( i = 0; i < width -1; ) { unsigned char r,b; b = CLIP(( (unsigned int)source[ lineoffset + i ] * bgain ) / 4096); r = CLIP(( (unsigned int)source[ lineoffset + i + width + 1] * rgain ) / 4096); *dest++ = r; *dest++ = ( (unsigned int)source[ lineoffset + i + width ] + (unsigned int)source[ lineoffset + i + 1]) / 2; *dest++ = b; i++; *dest++ = r; *dest++ = ( (unsigned int)source[ lineoffset + i + width + 1 ] + (int)source[ lineoffset + i ]) / 2; *dest++ = b; i++; } lineoffset = (j+1)*width; //GBGBG //RGRGR //GBGBG for( i = 0; i < width -1; ) { unsigned char r,b; b = CLIP(( (unsigned int)source[ lineoffset + i + width ] * bgain ) / 4096); r = CLIP(( (unsigned int)source[ lineoffset + i + 1 ] * rgain ) / 4096); *dest++ = r; *dest++ = ( (unsigned int)source[ lineoffset + i + width + 1 ] + (int)source[ lineoffset + i ]) / 2; *dest++ = b; i++; *dest++ = r; *dest++ = ( (unsigned int)source[ lineoffset + i + width ] + (int)source[ lineoffset + i + 1 ]) / 2; *dest++ = b; i++; } } } void debayer_ccm_rgb24_edge( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ) { int i,j; int dest_offset = 0; rgb24pixel_t *dest = (rgb24pixel_t*)destbuf->data; unsigned char *source = srcbuf->data; int width = destbuf->format.size.width; int height = destbuf->format.size.height; for( j = 2; j < height - 2; j+=2 ) { int lineoffset = j * width; dest_offset = j * width + 1; for( i = 1; i < width - 2; ) { rgb24pixel_t pixel; int g1 = source[ lineoffset + i - 1 ]; int g2 = source[ lineoffset + i + 1 ]; int g3 = source[ ( lineoffset + i ) - width ]; int g4 = source[ lineoffset + i + width ]; int d1 = ABS( g1 - g2 ); int d2 = ABS( g3 - g4 ); pixel.c.b = source[ lineoffset + i ]; pixel.c.r = ( ( (int)source[ ( ( lineoffset + i ) - width ) + 1 ] + (int)source[ ( lineoffset + i + width ) + 1 ] + (int)source[ ( ( lineoffset + i ) - width ) - 1 ] + (int)source[ ( lineoffset + i + width ) - 1 ] ) / 4 ); if( d1 < d2 ) { pixel.c.g = ( g1 + g2 ) / 2; } else { pixel.c.g = ( g3 + g4 ) / 2; } if( data->use_ccm ) { pixel.c.r = CLIP( (pixel.c.r * CRR(data->ccm) + pixel.c.g * CRG(data->ccm) + pixel.c.b * CRB(data->ccm))/1024 ); pixel.c.g = CLIP( (pixel.c.r * CGR(data->ccm) + pixel.c.g * CGG(data->ccm) + pixel.c.b * CGB(data->ccm))/1024 ); pixel.c.b = CLIP( (pixel.c.r * CBR(data->ccm) + pixel.c.g * CBG(data->ccm) + pixel.c.b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { pixel.c.r = CLIP(( pixel.c.r * data->rgain ) / 4096); pixel.c.b = CLIP(( pixel.c.b * data->bgain ) / 4096); } dest[dest_offset++].combined = pixel.combined; i++; pixel.c.g = g2; pixel.c.b = ( (int)source[ ( lineoffset + i ) - 1 ] + (int)source[ ( lineoffset + i ) + 1 ] ) / 2; pixel.c.r = ( (int)source[ ( lineoffset + i ) - width ] + (int)source[ lineoffset + i + width ] ) / 2; if( data->use_ccm ) { pixel.c.r = CLIP( (pixel.c.r * CRR(data->ccm) + pixel.c.g * CRG(data->ccm) + pixel.c.b * CRB(data->ccm))/1024 ); pixel.c.g = CLIP( (pixel.c.r * CGR(data->ccm) + pixel.c.g * CGG(data->ccm) + pixel.c.b * CGB(data->ccm))/1024 ); pixel.c.b = CLIP( (pixel.c.r * CBR(data->ccm) + pixel.c.g * CBG(data->ccm) + pixel.c.b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { pixel.c.r = CLIP(( pixel.c.r * data->rgain ) / 4096); pixel.c.b = CLIP(( pixel.c.b * data->bgain ) / 4096); } dest[dest_offset++].combined = pixel.combined; i++; } lineoffset += width; dest_offset = (j+1) * width + 2; for( i = 2; i < width - 3; ) { rgb24pixel_t pixel; int g1 = source[ lineoffset + i - 1 ]; int g2 = source[ lineoffset + i + 1 ]; int g3 = source[ ( lineoffset + i ) - width ]; int g4 = source[ lineoffset + i + width ]; int d1 = ABS( g1 - g2 ); int d2 = ABS( g3 - g4 ); pixel.c.r = source[ lineoffset + i ]; if( d1 < d2 ) { pixel.c.g = ( g1 + g2 ) / 2; } else { pixel.c.g = ( g3 + g4 ) / 2; } pixel.c.b = ( ( (int)source[ ( ( lineoffset + i ) - width ) + 1 ] + (int)source[ ( lineoffset + i + width ) + 1 ] + (int)source[ ( ( lineoffset + i ) - width ) - 1 ] + (int)source[ ( lineoffset + i + width ) - 1 ] ) / 4 ); if( data->use_ccm ) { pixel.c.r = CLIP( (pixel.c.r * CRR(data->ccm) + pixel.c.g * CRG(data->ccm) + pixel.c.b * CRB(data->ccm))/1024 ); pixel.c.g = CLIP( (pixel.c.r * CGR(data->ccm) + pixel.c.g * CGG(data->ccm) + pixel.c.b * CGB(data->ccm))/1024 ); pixel.c.b = CLIP( (pixel.c.r * CBR(data->ccm) + pixel.c.g * CBG(data->ccm) + pixel.c.b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { pixel.c.r = CLIP(( pixel.c.r * data->rgain ) / 4096); pixel.c.b = CLIP(( pixel.c.b * data->bgain ) / 4096); } dest[dest_offset++].combined = pixel.combined; i++; pixel.c.g = g2; pixel.c.r = ( (int)source[ ( lineoffset + i ) - 1 ] + (int)source[ ( lineoffset + i ) + 1 ] ) / 2; pixel.c.b = ( (int)source[ ( lineoffset + i ) - width ] + (int)source[ lineoffset + i + width ] ) / 2; if( data->use_ccm ) { pixel.c.r = CLIP( (pixel.c.r * CRR(data->ccm) + pixel.c.g * CRG(data->ccm) + pixel.c.b * CRB(data->ccm))/1024 ); pixel.c.g = CLIP( (pixel.c.r * CGR(data->ccm) + pixel.c.g * CGG(data->ccm) + pixel.c.b * CGB(data->ccm))/1024 ); pixel.c.b = CLIP( (pixel.c.r * CBR(data->ccm) + pixel.c.g * CBG(data->ccm) + pixel.c.b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { pixel.c.r = CLIP(( pixel.c.r * data->rgain ) / 4096); pixel.c.b = CLIP(( pixel.c.b * data->bgain ) / 4096); } dest[dest_offset++].combined = pixel.combined; i++; } } } void debayer_ccm_uyvy( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ) { int i,j; int dest_offset = 0; unsigned char *dest = destbuf->data; unsigned char *source = srcbuf->data; int width = destbuf->format.size.width; int height = destbuf->format.size.height; for( j = 2; j < height - 2; j+=2 ) { int lineoffset = j * width; dest_offset = j * width * 2 + 2; for( i = 1; i < width - 2; ) { int r, g, b; int g1 = source[ lineoffset + i - 1 ]; int g2 = source[ lineoffset + i + 1 ]; int g3 = source[ ( lineoffset + i ) - width ]; int g4 = source[ lineoffset + i + width ]; int d1 = ABS( g1 - g2 ); int d2 = ABS( g3 - g4 ); b = source[ lineoffset + i ]; r = ( ( (int)source[ ( ( lineoffset + i ) - width ) + 1 ] + (int)source[ ( lineoffset + i + width ) + 1 ] + (int)source[ ( ( lineoffset + i ) - width ) - 1 ] + (int)source[ ( lineoffset + i + width ) - 1 ] ) / 4 ); if( d1 < d2 ) { g = ( g1 + g2 ) / 2; } else { g = ( g3 + g4 ) / 2; } if( data->use_ccm ) { r = CLIP( (r * CRR(data->ccm) + g * CRG(data->ccm) + b * CRB(data->ccm))/1024 ); g = CLIP( (r * CGR(data->ccm) + g * CGG(data->ccm) + b * CGB(data->ccm))/1024 ); b = CLIP( (r * CBR(data->ccm) + g * CBG(data->ccm) + b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { r = CLIP(( r * data->rgain ) / 1024); b = CLIP(( b * data->bgain ) / 1024); } dest[dest_offset++] = YUV_V(r,g,b); dest[dest_offset++] = YUV_Y(r,g,b); i++; g = g2; b = ( (int)source[ ( lineoffset + i ) - 1 ] + (int)source[ ( lineoffset + i ) + 1 ] ) / 2; r = ( (int)source[ ( lineoffset + i ) - width ] + (int)source[ lineoffset + i + width ] ) / 2; if( data->use_ccm ) { r = CLIP( (r * CRR(data->ccm) + g * CRG(data->ccm) + b * CRB(data->ccm))/1024 ); g = CLIP( (r * CGR(data->ccm) + g * CGG(data->ccm) + b * CGB(data->ccm))/1024 ); b = CLIP( (r * CBR(data->ccm) + g * CBG(data->ccm) + b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { r = CLIP(( r * data->rgain ) / 1024); b = CLIP(( b * data->bgain ) / 1024); } dest[dest_offset++] = YUV_U(r,g,b); dest[dest_offset++] = YUV_Y(r,g,b); i++; } lineoffset += width; dest_offset = (j+1) * width * 2 + 4; for( i = 2; i < width - 3; ) { int r, g, b; int g1 = source[ lineoffset + i - 1 ]; int g2 = source[ lineoffset + i + 1 ]; int g3 = source[ ( lineoffset + i ) - width ]; int g4 = source[ lineoffset + i + width ]; int d1 = ABS( g1 - g2 ); int d2 = ABS( g3 - g4 ); r = source[ lineoffset + i ]; if( d1 < d2 ) { g = ( g1 + g2 ) / 2; } else { g = ( g3 + g4 ) / 2; } b = ( ( (int)source[ ( ( lineoffset + i ) - width ) + 1 ] + (int)source[ ( lineoffset + i + width ) + 1 ] + (int)source[ ( ( lineoffset + i ) - width ) - 1 ] + (int)source[ ( lineoffset + i + width ) - 1 ] ) / 4 ); if( data->use_ccm ) { r = CLIP( (r * CRR(data->ccm) + g * CRG(data->ccm) + b * CRB(data->ccm))/1024 ); g = CLIP( (r * CGR(data->ccm) + g * CGG(data->ccm) + b * CGB(data->ccm))/1024 ); b = CLIP( (r * CBR(data->ccm) + g * CBG(data->ccm) + b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { r = CLIP(( r * data->rgain ) / 1024); b = CLIP(( b * data->bgain ) / 1024); } dest[dest_offset++] = YUV_U(r,g,b); dest[dest_offset++] = YUV_Y(r,g,b); i++; g = g2; r = ( (int)source[ ( lineoffset + i ) - 1 ] + (int)source[ ( lineoffset + i ) + 1 ] ) / 2; b = ( (int)source[ ( lineoffset + i ) - width ] + (int)source[ lineoffset + i + width ] ) / 2; if( data->use_ccm ) { r = CLIP( (r * CRR(data->ccm) + g * CRG(data->ccm) + b * CRB(data->ccm))/1024 ); g = CLIP( (r * CGR(data->ccm) + g * CGG(data->ccm) + b * CGB(data->ccm))/1024 ); b = CLIP( (r * CBR(data->ccm) + g * CBG(data->ccm) + b * CBB(data->ccm))/1024 ); } else if( data->use_rbgain ) { r = CLIP(( r * data->rgain ) / 1024); b = CLIP(( b * data->bgain ) / 1024); } dest[dest_offset++] = YUV_V(r,g,b); dest[dest_offset++] = YUV_Y(r,g,b); i++; } } } #ifdef __SSE2__ typedef union { __m128i m128i; unsigned char i8[16]; }m128iu; void debayer_sse2( unicap_data_buffer_t *destbuf, unicap_data_buffer_t* srcbuf, debayer_data_t *data ) { unsigned char *dest = destbuf->data; unsigned char *source = srcbuf->data; int width = srcbuf->format.size.width; int height = srcbuf->format.size.height; int i,j; int dest_offset = 0; int imgwidth = width; for( j = 2; j < (height); j += 2 ) { int lineoffset = j * imgwidth; dest_offset = (j) * width * 3; // RGRGRGRGRGRG // GBGBGBGBGBGB <<- // RGRGRGRGRGRG for( i = 0; i < (width ); i += 16) { int k; m128iu b1, b2, r1, r2; m128iu avg1, avg2, avg3; r1.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset - imgwidth + i) ); r2.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset + imgwidth + i) ); // r1 = RG avg1.m128i = _mm_avg_epu8( b1.m128i, b2.m128i ); // avg1 = RG' b1.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset + i - 1) ); b2.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset + i + 1) ); // b1 = BG avg2.m128i = _mm_avg_epu8( b1.m128i, b2.m128i ); // avg2 = B'G' avg3.m128i = _mm_avg_epu8( avg1.m128i, avg2.m128i ); // avg3 = XG for( k = 0; k < 16; k+=2 ){ dest[dest_offset++] = r1.i8[k]; dest[dest_offset++] = b1.i8[k+1]; dest[dest_offset++] = avg2.i8[k]; dest[dest_offset++] = r1.i8[k]; dest[dest_offset++] = avg2.i8[k+1]; dest[dest_offset++] = b2.i8[k]; } } lineoffset += imgwidth; dest_offset = ( j + 1 ) * width * 3; // GBGBGBGBGBGB // RGRGRGRGRGRG <<- // GBGBGBGBGBGB for( i = 0; i < (width); i += 16) { m128iu b1, b2, r1, r2; m128iu avg1, avg2, avg3; int k; b1.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset - imgwidth + i) ); b2.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset + imgwidth + i) ); avg1.m128i = _mm_avg_epu8( b1.m128i, b2.m128i ); // avg1 = G'B r1.m128i = _mm_loadu_si128( (__m128i*)(source + lineoffset + i - 1) ); r2.m128i = _mm_loadu_si128( (__m128i*)(source +lineoffset + i + 1 ) ); // r1 = GRGR // r2 = GRGR avg2.m128i = _mm_avg_epu8( r1.m128i, r2.m128i ); // avg2 = G'R' avg3.m128i = _mm_avg_epu8( avg1.m128i, avg2.m128i ); // avg3 = GX for( k = 0; k < 16; k += 2 ){ dest[dest_offset++] = r1.i8[k+1]; dest[dest_offset++] = avg3.i8[k]; dest[dest_offset++] = avg1.i8[k+1]; dest[dest_offset++] = avg2.i8[k+1]; dest[dest_offset++] = r2.i8[k]; dest[dest_offset++] = avg1.i8[k+1]; } } } } #endif libunicap/cpi/euvccam/euvccam_cpi.h0000644000175000017500000000324113164711411020102 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef EUVCCAM_CPI_H_ # define EUVCCAM_CPI_H_ #include #include #include #include #include "queue.h" #include "debayer.h" #if EUVCCAM_DEBUG #define DEBUG #endif #include "debug.h" #include "euvccam_usb.h" struct euvccam_handle { euvccam_usb_device_t dev; unsigned char type_flag; int removed; unicap_handle_t unicap_handle; unicap_event_callback_t event_callback; int devspec_index; struct euvccam_video_format_description *current_format; unicap_queue_t buffer_in_queue; unicap_queue_t buffer_out_queue; pthread_t capture_thread; int capture_thread_quit; int capture_running; int streaming_endpoint; char current_ae_mode; unsigned int current_wb_r; unsigned int current_wb_g; debayer_data_t debayer_data; }; typedef struct euvccam_handle *euvccam_handle_t; #endif /* !EUVCCAM_CPI_H_ */ libunicap/cpi/euvccam/Makefile.am0000644000175000017500000000137313164711411017513 0ustar zmoelnigzmoelnigINCLUDES = -I../include -I../../include -I../../ -I../../common if ENABLE_STATIC_CPI noinst_LTLIBRARIES=libeuvccam_cpi.la libeuvccam_cpi_la_LIBADD=-lpthread -lrt else libcpi_LTLIBRARIES=libeuvccam_cpi.la libeuvccam_cpi_la_LIBADD=-lpthread -L../../src/.libs/ -lunicap -lrt endif libcpidir = $(libdir)/unicap$(pkg_version)/cpi #libeuvccam_cpi_la_CFLAGS=-msse2 -O2 -g libeuvccam_cpi_la_CFLAGS=-O2 -g libeuvccam_cpi_la_LDFLAGS=-module -avoid-version libeuvccam_cpi_la_SOURCES= \ euvccam_cpi.c euvccam_cpi.h \ euvccam_device.c euvccam_device.h \ euvccam_capture.c euvccam_capture.h \ euvccam_devspec.c euvccam_devspec.h \ euvccam_colorproc.c euvccam_colorproc.h \ euvccam_usb.c euvccam_usb.h \ debayer.c debayer.h \ queue.c queue.h \ logging.c logging.h libunicap/cpi/euvccam/euvccam_devspec.h0000644000175000017500000000415213164711411020762 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __EUVCCAM_VIDEO_FORMATS_H__ #define __EUVCCAM_VIDEO_FORMATS_H__ #include #define EUVCCAM_HAS_AUTO_EXPOSURE ( 1 << 0 ) #define EUVCCAM_HAS_AUTO_GAIN ( 1 << 1 ) #define EUVCCAM_FORMAT_IS_PARTIAL_SCAN ( 1 << 0 ) typedef unicap_status_t(*euvccam_property_func_t)(euvccam_handle_t handle,unicap_property_t *property); typedef void(*euvccam_convert_func_t)(euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ); struct euvccam_video_format_description { int format_index; int frame_index; unicap_format_t format; int frame_rate_count; double *frame_rates; int *frame_rate_map; int usb_buffer_size; euvccam_convert_func_t convert_func; int flags; }; typedef struct euvccam_video_format_description euvccam_video_format_description_t; struct euvccam_property { unicap_property_t property; euvccam_property_func_t get_func; euvccam_property_func_t set_func; euvccam_property_func_t enumerate_func; }; typedef struct euvccam_property euvccam_property_t; struct euvccam_devspec { unsigned short pid; unsigned char type_flag; unsigned int flags; int format_count; struct euvccam_video_format_description *format_list; int property_count; struct euvccam_property *property_list; }; extern struct euvccam_devspec euvccam_devspec[]; #endif//__EUVCCAM_VIDEO_FORMATS_H__ libunicap/cpi/euvccam/euvccam_cpi.c0000644000175000017500000002561513164711411020106 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include "euvccam_cpi.h" #include "euvccam_usb.h" #include "unicap_cpi.h" #include "queue.h" #include "euvccam_device.h" #include "euvccam_devspec.h" #include "euvccam_capture.h" static unicap_status_t euvccam_enumerate_devices( unicap_device_t *device, int index ); static unicap_status_t euvccam_open( void **cpi_data, unicap_device_t *device ); static unicap_status_t euvccam_close( euvccam_handle_t handle ); static unicap_status_t euvccam_reenumerate_formats( euvccam_handle_t handle, int *_pcount ); static unicap_status_t euvccam_enumerate_formats( euvccam_handle_t handle, unicap_format_t *format, int index ); static unicap_status_t euvccam_set_format( euvccam_handle_t handle, unicap_format_t *format ); static unicap_status_t euvccam_get_format( euvccam_handle_t handle, unicap_format_t *format ); static unicap_status_t euvccam_reenumerate_properties( euvccam_handle_t handle, int *_pcount ); static unicap_status_t euvccam_enumerate_properties( euvccam_handle_t handle, unicap_property_t *property, int index ); static unicap_status_t euvccam_set_property( euvccam_handle_t handle, unicap_property_t *property ); static unicap_status_t euvccam_get_property( euvccam_handle_t handle, unicap_property_t *property ); static unicap_status_t euvccam_capture_start( euvccam_handle_t handle ); static unicap_status_t euvccam_capture_stop( euvccam_handle_t handle ); static unicap_status_t euvccam_queue_buffer( euvccam_handle_t handle, unicap_data_buffer_t *buffer ); static unicap_status_t euvccam_dequeue_buffer( euvccam_handle_t handle, unicap_data_buffer_t **buffer ); static unicap_status_t euvccam_wait_buffer( euvccam_handle_t handle, unicap_data_buffer_t **buffer ); static unicap_status_t euvccam_poll_buffer( euvccam_handle_t handle, int *count ); static unicap_status_t euvccam_set_event_notify( euvccam_handle_t handle, unicap_event_callback_t func, unicap_handle_t unicap_handle ); static struct _unicap_cpi cpi_s = { cpi_version: 1<<16, cpi_capabilities: 0x3ffff, cpi_flags: UNICAP_CPI_SERIALIZED, cpi_enumerate_devices: euvccam_enumerate_devices, cpi_open: (cpi_open_t)euvccam_open, cpi_close: (cpi_close_t)euvccam_close, cpi_reenumerate_formats: (cpi_reenumerate_formats_t)euvccam_reenumerate_formats, cpi_enumerate_formats: (cpi_enumerate_formats_t)euvccam_enumerate_formats, cpi_set_format: (cpi_set_format_t)euvccam_set_format, cpi_get_format: (cpi_get_format_t)euvccam_get_format, cpi_reenumerate_properties: (cpi_reenumerate_properties_t)euvccam_reenumerate_properties, cpi_enumerate_properties: (cpi_enumerate_properties_t)euvccam_enumerate_properties, cpi_set_property: (cpi_set_property_t)euvccam_set_property, cpi_get_property: (cpi_get_property_t)euvccam_get_property, cpi_capture_start: (cpi_capture_start_t)euvccam_capture_start, cpi_capture_stop: (cpi_capture_stop_t)euvccam_capture_stop, cpi_queue_buffer: (cpi_queue_buffer_t)euvccam_queue_buffer, cpi_dequeue_buffer: (cpi_dequeue_buffer_t)euvccam_dequeue_buffer, cpi_wait_buffer: (cpi_wait_buffer_t)euvccam_wait_buffer, cpi_poll_buffer: (cpi_poll_buffer_t)euvccam_poll_buffer, cpi_set_event_notify: (cpi_set_event_notify_t)euvccam_set_event_notify, }; unicap_status_t cpi_register( struct _unicap_cpi *reg_data ) { memcpy( reg_data, &cpi_s, sizeof( struct _unicap_cpi ) ); log_init(); euvccam_usb_init(); return STATUS_SUCCESS; } static unicap_status_t euvccam_enumerate_devices( unicap_device_t *device, int index ) { unicap_status_t status = STATUS_NO_MATCH; euvccam_usb_device_t *dev; unicap_void_device( device ); dev = euvccam_usb_find_device( index ); if( dev ){ strcpy( device->identifier, dev->identifier ); strcpy( device->model_name, dev->strProduct ); strcpy( device->vendor_name, dev->strVendor ); device->vendor_id = dev->idVendor; device->model_id = dev->serial; strcpy( device->cpi_layer, "euvccam_cpi" ); status = STATUS_SUCCESS; } return status; } static unicap_status_t euvccam_open( void **cpi_data, unicap_device_t *device ) { unicap_status_t status = STATUS_FAILURE; euvccam_handle_t handle; int i; handle = malloc( sizeof( struct euvccam_handle ) ); if( !handle ) return STATUS_FAILURE; memset( handle, 0x0, sizeof( struct euvccam_handle ) ); *cpi_data = handle; status = euvccam_usb_open_device( device, &handle->dev ); if( !SUCCESS( status ) ) goto err; status = euvccam_read_vendor_register( handle->dev.fd, 0x1a, &handle->type_flag ); if( !SUCCESS( status ) ) goto err; for( i = 0; euvccam_devspec[i].pid != 0; i++ ) { if( ( euvccam_devspec[i].pid == handle->dev.idProduct ) && ( euvccam_devspec[i].type_flag == handle->type_flag ) ) { handle->devspec_index = i; break; } } euvccam_device_get_format( handle, &handle->current_format ); if( !handle->current_format ) euvccam_set_format( handle, &euvccam_devspec[handle->devspec_index].format_list[0].format ); _init_queue( &handle->buffer_in_queue ); _init_queue( &handle->buffer_out_queue ); handle->debayer_data.rgain = 4096; handle->debayer_data.bgain = 4096; handle->debayer_data.use_rbgain = 1; return status; err: if( handle->dev.fd >= 0 ) euvccam_usb_close_device( &handle->dev ); free( handle ); return status; } static unicap_status_t euvccam_close( euvccam_handle_t handle ) { if( handle->dev.fd >= 0 ) euvccam_usb_close_device( &handle->dev ); free( handle ); return STATUS_SUCCESS; } static unicap_status_t euvccam_reenumerate_formats( euvccam_handle_t handle, int *_pcount ) { if( _pcount ) *_pcount = euvccam_devspec[handle->devspec_index].format_count; return STATUS_SUCCESS; } static unicap_status_t euvccam_enumerate_formats( euvccam_handle_t handle, unicap_format_t *format, int index ) { unicap_status_t status = STATUS_NO_MATCH; if( (index >=0) && (index < euvccam_devspec[handle->devspec_index].format_count) ) { unicap_copy_format( format, &euvccam_devspec[handle->devspec_index].format_list[index].format ); status = STATUS_SUCCESS; } return status; } static unicap_status_t euvccam_set_format( euvccam_handle_t handle, unicap_format_t *format ) { return euvccam_device_set_format( handle, format ); } static unicap_status_t euvccam_get_format( euvccam_handle_t handle, unicap_format_t *format ) { unicap_status_t status = STATUS_FAILURE; if( handle->current_format ){ unicap_copy_format( format, &handle->current_format->format ); status = STATUS_SUCCESS; } return status; } static unicap_status_t euvccam_reenumerate_properties( euvccam_handle_t handle, int *_pcount ) { int count = euvccam_devspec[ handle->devspec_index ].property_count; if( _pcount ){ int i; for( i = 0; i < count; i++ ){ if( euvccam_devspec[ handle->devspec_index ].property_list[ i ].enumerate_func ){ unicap_property_t property; unicap_void_property( &property ); if( !SUCCESS( euvccam_devspec[ handle->devspec_index ].property_list[ i ].enumerate_func( handle, &property ) ) ){ count--; } } } *_pcount = count; } return STATUS_SUCCESS; } static unicap_status_t euvccam_enumerate_properties( euvccam_handle_t handle, unicap_property_t *property, int index ) { unicap_status_t status = STATUS_NO_MATCH; if( index < euvccam_devspec[ handle->devspec_index ].property_count ){ unicap_copy_property( property, &euvccam_devspec[ handle->devspec_index ].property_list[index].property ); status = STATUS_SUCCESS; } return status; } static unicap_status_t euvccam_set_property( euvccam_handle_t handle, unicap_property_t *property ) { int i; unicap_status_t status = STATUS_NO_MATCH; for( i = 0; i < euvccam_devspec[ handle->devspec_index ].property_count; i++ ){ if( !strncmp( property->identifier, euvccam_devspec[ handle->devspec_index ].property_list[i].property.identifier, sizeof( property->identifier ) ) ){ status = euvccam_devspec[ handle->devspec_index ].property_list[ i ].set_func( handle, property ); } } return status; } static unicap_status_t euvccam_get_property( euvccam_handle_t handle, unicap_property_t *property ) { int i; unicap_status_t status = STATUS_NO_MATCH; for( i = 0; i < euvccam_devspec[ handle->devspec_index ].property_count; i++ ){ if( !strncmp( property->identifier, euvccam_devspec[ handle->devspec_index ].property_list[i].property.identifier, sizeof( property->identifier ) ) ){ void *property_data = property->property_data; int property_data_size = property->property_data_size; unicap_copy_property( property, &euvccam_devspec[ handle->devspec_index ].property_list[ i ].property ); property->property_data = property_data; property->property_data_size = property_data_size; status = euvccam_devspec[ handle->devspec_index ].property_list[ i ].get_func( handle, property ); } } return status; } static unicap_status_t euvccam_capture_start( euvccam_handle_t handle ) { return euvccam_capture_start_capture( handle ); } static unicap_status_t euvccam_capture_stop( euvccam_handle_t handle ) { return euvccam_capture_stop_capture( handle ); } static unicap_status_t euvccam_queue_buffer( euvccam_handle_t handle, unicap_data_buffer_t *buffer ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t euvccam_dequeue_buffer( euvccam_handle_t handle, unicap_data_buffer_t **buffer ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t euvccam_wait_buffer( euvccam_handle_t handle, unicap_data_buffer_t **buffer ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t euvccam_poll_buffer( euvccam_handle_t handle, int *count ) { return STATUS_NOT_IMPLEMENTED; } static unicap_status_t euvccam_set_event_notify( euvccam_handle_t handle, unicap_event_callback_t func, unicap_handle_t unicap_handle ) { handle->event_callback = func; handle->unicap_handle = unicap_handle; return STATUS_SUCCESS; } libunicap/cpi/euvccam/euvccam_device.h0000644000175000017500000001355013164711411020572 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __EUVCCAM_DEVICE_H__ #define __EUVCCAM_DEVICE_H__ #include #define EUVCCAM_SYSTEM_BUFFER_COUNT 8 struct probe_control { unsigned short bmHint; unsigned char bFormatIndex; unsigned char bFrameIndex; unsigned long dwFrameInterval; unsigned short wKeyFrameRate; unsigned short wPFrameRate; unsigned short wCompQuality; unsigned short wCompWindowSize; unsigned short wDelay; unsigned long dwMaxVideoFrameSize; unsigned long dwMaxPayloadTransferSize; unsigned long dwClockFrequency; unsigned char bmFramingInfo; unsigned char bPreferedVersion; unsigned char bMinVersion; unsigned char bMaxVersion; }; struct euvccam_iic_command { unsigned char devaddr; unsigned char addr; unsigned short value; }; struct usb_device *euvccam_find_device( int index ); struct usb_device *euvccam_find_device_by_id( char *identifier ); unicap_status_t euvccam_fill_device_struct( struct usb_device *dev, unicap_device_t *device ); unicap_status_t euvccam_read_vendor_register( int fd, int index, unsigned char *val ); unicap_status_t euvccam_write_vendor_register( int fd, int index, unsigned char val ); unicap_status_t euvccam_device_get_format( euvccam_handle_t handle, struct euvccam_video_format_description **format ); unicap_status_t euvccam_device_set_format( euvccam_handle_t handle, unicap_format_t *format ); unicap_status_t euvccam_device_set_exposure( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_exposure( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_gain( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_gain( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_white_balance( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_white_balance( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_white_balance_mode( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_white_balance_mode( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_frame_rate( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_frame_rate( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_enumerate_frame_rate( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_trigger( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_trigger( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_enumerate_trigger( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_software_trigger( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_software_trigger( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_enumerate_software_trigger( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_pixel_clock( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_pixel_clock( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_reset_mt9v024( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_reset_mt9v024( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_write_iic( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_read_iic( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_enumerate_gpout( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_get_gpout( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_gpout( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_enable_hdr (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_get_enable_hdr (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_enumerate_hdr (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_set_hdr_shutter (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_get_hdr_shutter (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_set_hdr_vstep (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_get_hdr_vstep (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_set_uart (euvccam_handle_t handle, unicap_property_t *property); unicap_status_t euvccam_device_get_uart( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_enumerate_uart( euvccam_handle_t handle, unicap_property_t *property ); unicap_status_t euvccam_device_set_test (euvccam_handle_t handle, unicap_property_t *property) ; #endif//__EUVCCAM_DEVICE_H__ libunicap/cpi/euvccam/euvccam_devspec.c0000644000175000017500000015137013164711411020762 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "euvccam_cpi.h" #include "euvccam_device.h" #include "euvccam_devspec.h" #include "euvccam_colorproc.h" #define N_ELEMENTS(a) (sizeof( a )/ sizeof(( a )[0] )) #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #define N_(x) x #define TRIGGER_FREE_RUNNING "free running" #define TRIGGER_FALLING_EDGE "trigger on falling edge" #define TRIGGER_RISING_EDGE "trigger on rising edge" static char* trigger_menu[] = { N_(TRIGGER_FREE_RUNNING), N_(TRIGGER_RISING_EDGE) }; static unicap_rect_t euvccam_WVGA_sizes[] = { { 0,0,640,480 }, { 0,0,744,480 }, }; static double format_8201_framerates[] = { 30, 15, 7.5, 3.75 }; static int format_8201_framerate_map[] = { 0, 1, 2, 3 }; static euvccam_property_t properties_8201[] = { { { identifier: N_("Shutter"), category: N_("Exposure"), unit: "s", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0.0001, max: 0.25 } }, stepping: 0.0001, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_exposure, set_func: euvccam_device_set_exposure, enumerate_func: NULL, }, { { identifier: N_("Gain"), category: N_("Exposure"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 16, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_gain, set_func: euvccam_device_set_gain, enumerate_func: NULL, }, { { identifier: "White Balance Mode", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_white_balance_mode, set_func: euvccam_device_set_white_balance_mode, enumerate_func: NULL, }, { { identifier: "White Balance Red", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 63}, {range: { min: 0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_white_balance, set_func: euvccam_device_set_white_balance, enumerate_func: NULL, }, { { identifier: "White Balance Blue", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 63}, {range: { min: 0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_white_balance, set_func: euvccam_device_set_white_balance, enumerate_func: NULL, }, { { identifier: "Frame Rate", category: "Video", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 10, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_VALUE_LIST, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_frame_rate, set_func: euvccam_device_set_frame_rate, enumerate_func: euvccam_device_enumerate_frame_rate, }, #if 1 { { identifier: "Pixel Clock", category: "Video", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 5, max: 120 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_pixel_clock, set_func: euvccam_device_set_pixel_clock, enumerate_func: NULL, }, #endif { { identifier: N_("trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {menu_item: TRIGGER_FREE_RUNNING}, {menu: { menu_items: trigger_menu, menu_item_count: sizeof( trigger_menu ) / sizeof( char * ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_trigger, set_func: euvccam_device_set_trigger, enumerate_func: euvccam_device_enumerate_trigger, }, #if 0 { { identifier: N_("reset sensor"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_reset_mt9v024, set_func: euvccam_device_set_reset_mt9v024, }, #endif { { identifier: "IIC Command", category: "Device", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 5, max: 120 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_read_iic, set_func: euvccam_device_write_iic, enumerate_func: NULL, }, }; static euvccam_property_t properties_8206[] = { { { identifier: "Shutter", category: "Exposure", unit: "s", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0.0001, max: 0.25 } }, stepping: 0.0001, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_exposure, set_func: euvccam_device_set_exposure, enumerate_func: NULL, }, { { identifier: "Gain", category: "Exposure", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_gain, set_func: euvccam_device_set_gain, enumerate_func: NULL, }, { { identifier: "White Balance Mode", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_white_balance_mode, set_func: euvccam_device_set_white_balance_mode, enumerate_func: NULL, }, { { identifier: "White Balance Red", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 63}, {range: { min: 0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_white_balance, set_func: euvccam_device_set_white_balance, enumerate_func: NULL, }, { { identifier: "White Balance Blue", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 63}, {range: { min: 0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_white_balance, set_func: euvccam_device_set_white_balance, enumerate_func: NULL, }, /* { */ /* { */ /* identifier: "Frame Rate", */ /* category: "Video", */ /* unit: "", */ /* relations: NULL, */ /* relations_count: 0, */ /* {value: 0}, */ /* {range: { min: 0, max: 0 } }, */ /* stepping: 1.0, */ /* type: UNICAP_PROPERTY_TYPE_VALUE_LIST, */ /* flags: UNICAP_FLAGS_MANUAL, */ /* flags_mask: UNICAP_FLAGS_MANUAL, */ /* property_data: NULL, */ /* property_data_size: 0, */ /* }, */ /* get_func: euvccam_device_get_frame_rate, */ /* set_func: euvccam_device_set_frame_rate, */ /* enumerate_func: euvccam_device_enumerate_frame_rate, */ /* }, */ { { identifier: N_("trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {menu_item: TRIGGER_FREE_RUNNING}, {menu: { menu_items: trigger_menu, menu_item_count: sizeof( trigger_menu ) / sizeof( char * ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_trigger, set_func: euvccam_device_set_trigger, enumerate_func: euvccam_device_enumerate_trigger, }, #if 1 { { identifier: "Pixel Clock", category: "Video", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 5, max: 120 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_pixel_clock, set_func: euvccam_device_set_pixel_clock, enumerate_func: NULL, }, #endif { { identifier: "IIC Command", category: "Device", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 5, max: 120 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_read_iic, set_func: euvccam_device_write_iic, enumerate_func: NULL, }, { { identifier: N_("GP Out"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_gpout, set_func: euvccam_device_set_gpout, enumerate_func: euvccam_device_enumerate_gpout, }, { { identifier: N_("UART"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0.0} }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_uart, set_func: euvccam_device_set_uart, enumerate_func: NULL, }, { { identifier: N_("TEST"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 255.0} }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_uart, set_func: euvccam_device_set_test, enumerate_func: NULL, }, { { identifier: N_("software trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_software_trigger, set_func: euvccam_device_set_software_trigger, enumerate_func: euvccam_device_enumerate_software_trigger, }, }; static euvccam_property_t properties_8202_color[] = { { { identifier: "Shutter", category: "Exposure", unit: "s", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0.0001, max: 0.25 } }, stepping: 0.0001, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_exposure, set_func: euvccam_device_set_exposure, enumerate_func: NULL, }, { { identifier: "Gain", category: "Exposure", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 16, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_gain, set_func: euvccam_device_set_gain, enumerate_func: NULL, }, { { identifier: "Frame Rate", category: "Video", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_VALUE_LIST, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_frame_rate, set_func: euvccam_device_set_frame_rate, enumerate_func: euvccam_device_enumerate_frame_rate, }, { { identifier: "White Balance Mode", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 0.0}, {range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO | UNICAP_FLAGS_ONE_PUSH, property_data: NULL, property_data_size: 0, }, get_func: euvccam_colorproc_get_wbgain_mode, set_func: euvccam_colorproc_set_wbgain_mode, enumerate_func: NULL, }, { { identifier: "White Balance Blue", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 1.0}, {range: { min: 0.0, max: 8.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_colorproc_get_wbgain, set_func: euvccam_colorproc_set_wbgain, enumerate_func: NULL, }, { { identifier: "White Balance Red", category: "Color", unit: "", relations: NULL, relations_count: 0, {value: 1.0}, {range: { min: 0.0, max: 8.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_colorproc_get_wbgain, set_func: euvccam_colorproc_set_wbgain, enumerate_func: NULL, }, { { identifier: N_("trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {menu_item: TRIGGER_FREE_RUNNING}, {menu: { menu_items: trigger_menu, menu_item_count: sizeof( trigger_menu ) / sizeof( char * ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_trigger, set_func: euvccam_device_set_trigger, enumerate_func: euvccam_device_enumerate_trigger, }, { { identifier: N_("software trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_software_trigger, set_func: euvccam_device_set_software_trigger, enumerate_func: euvccam_device_enumerate_software_trigger, }, #if 0 { { identifier: N_("reset sensor"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_reset_mt9v024, set_func: euvccam_device_set_reset_mt9v024, }, #endif { { identifier: "IIC Command", category: "Device", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 5, max: 120 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_read_iic, set_func: euvccam_device_write_iic, enumerate_func: NULL, }, }; static euvccam_property_t properties_8202_mono[] = { { { identifier: "Shutter", category: "Exposure", unit: "s", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0.0001, max: 0.25 } }, stepping: 0.0001, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_exposure, set_func: euvccam_device_set_exposure, enumerate_func: NULL, }, { { identifier: "Gain", category: "Exposure", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 16, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_gain, set_func: euvccam_device_set_gain, enumerate_func: NULL, }, { { identifier: "Frame Rate", category: "Video", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_VALUE_LIST, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_get_frame_rate, set_func: euvccam_device_set_frame_rate, enumerate_func: euvccam_device_enumerate_frame_rate, }, { { identifier: N_("trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {menu_item: TRIGGER_FREE_RUNNING}, {menu: { menu_items: trigger_menu, menu_item_count: sizeof( trigger_menu ) / sizeof( char * ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_trigger, set_func: euvccam_device_set_trigger, enumerate_func: euvccam_device_enumerate_trigger, }, { { identifier: N_("software trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_software_trigger, set_func: euvccam_device_set_software_trigger, enumerate_func: euvccam_device_enumerate_software_trigger, }, #if 0 { { identifier: N_("reset sensor"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_reset_mt9v024, set_func: euvccam_device_set_reset_mt9v024, }, #endif { { identifier: "IIC Command", category: "Device", unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 5, max: 120 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0, }, get_func: euvccam_device_read_iic, set_func: euvccam_device_write_iic, enumerate_func: NULL, }, #if 0 { { identifier: N_("HDR Enable"), category: N_("hdr"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_enable_hdr, set_func: euvccam_device_enable_hdr, enumerate_func: euvccam_device_enumerate_hdr, }, { { identifier: N_("HDR Shutter 1"), category: N_("hdr"), unit: "s", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0.0001, max: 4 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_hdr_shutter, set_func: euvccam_device_set_hdr_shutter, enumerate_func: euvccam_device_enumerate_hdr, }, { { identifier: N_("HDR Shutter 2"), category: N_("hdr"), unit: "s", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0.0001, max: 4 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_hdr_shutter, set_func: euvccam_device_set_hdr_shutter, enumerate_func: euvccam_device_enumerate_hdr, }, { { identifier: N_("HDR VStep 1"), category: N_("hdr"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_hdr_vstep, set_func: euvccam_device_set_hdr_vstep, enumerate_func: euvccam_device_enumerate_hdr, }, { { identifier: N_("HDR VStep 2"), category: N_("hdr"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_hdr_vstep, set_func: euvccam_device_set_hdr_vstep, enumerate_func: euvccam_device_enumerate_hdr, }, { { identifier: N_("HDR VStep 3"), category: N_("hdr"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_hdr_vstep, set_func: euvccam_device_set_hdr_vstep, enumerate_func: euvccam_device_enumerate_hdr, }, { { identifier: N_("HDR VStep 4"), category: N_("hdr"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 63 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, get_func: euvccam_device_get_hdr_vstep, set_func: euvccam_device_set_hdr_vstep, enumerate_func: euvccam_device_enumerate_hdr, }, #endif }; static struct euvccam_video_format_description formats_8201[] = { { 2, 2, { identifier: "UYVY 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 640 * 480 * 2, fourcc: FOURCC( 'U', 'Y', 'V', 'Y' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8201_framerates ), format_8201_framerates, format_8201_framerate_map, 640 * 480 * 2, NULL, }, { 2, 1, { identifier: "UYVY 744x480", size: {0,0,744,480}, min_size: { 0,0,744,480 }, max_size: { 0,0,744,480 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 744 * 480 * 2, fourcc: FOURCC( 'U', 'Y', 'V', 'Y' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8201_framerates ), format_8201_framerates, format_8201_framerate_map, 744 * 480 * 2, NULL, }, { 1, 2, { identifier: "YUYV 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 640 * 480 * 2, fourcc: FOURCC( 'Y', 'U', 'Y', 'V' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8201_framerates ), format_8201_framerates, format_8201_framerate_map, 640 * 480 * 2, NULL, }, { 1, 1, { identifier: "YUYV 744x480", size: {0,0,744,480}, min_size: { 0,0,744,480 }, max_size: { 0,0,744,480 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 744 * 480 * 2, fourcc: FOURCC( 'Y', 'U', 'Y', 'V' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8201_framerates ), format_8201_framerates, format_8201_framerate_map, 744 * 480 * 2, NULL, }, }; static double format_8202_framerates[] = { 87, 60, 30, 25, 15, 7.5, 5}; static int format_8202_framerate_map[] = { 7, 6, 0, 1, 2, 3, 4}; static struct euvccam_video_format_description formats_8202_color[] = { /* { */ /* 1, */ /* 2, */ /* { identifier: "Y800 104x104", */ /* size: {0,0,104,104}, */ /* min_size: { 0,0,104,104 }, */ /* max_size: { 0,0,756,480 }, */ /* h_stepping: 16, */ /* v_stepping: 16, */ /* sizes: NULL, */ /* size_count: 0, */ /* bpp: 8, */ /* buffer_size: 104 * 104, */ /* fourcc: FOURCC( 'Y', '8', '0', '0' ), */ /* flags: 0, */ /* buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, */ /* system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, */ /* buffer_type: 0 */ /* }, */ /* N_ELEMENTS( format_8202_framerates ), */ /* format_8202_framerates, */ /* format_8202_framerate_map, */ /* 756 * 480, */ /* NULL, */ /* EUVCCAM_FORMAT_IS_PARTIAL_SCAN, */ /* }, */ { 1, 2, { identifier: "RGB24 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 640 * 480 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 640 * 480, euvccam_colorproc_by8_rgb24_nn, }, { 1, 1, { identifier: "RGB24 744x480", size: {0,0,744,480}, min_size: { 0,0,744,480 }, max_size: { 0,0,744,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 744 * 480 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 744 * 480, euvccam_colorproc_by8_rgb24_nn, }, { 1, 3, { identifier: "Y800 320x240", size: {0,0,320,240}, min_size: { 0,0,320,240 }, max_size: { 0,0,320,240 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 320 * 240, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 320 * 240, NULL, }, { 1, 2, { identifier: "Y800 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 640 * 480, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 640 * 480, NULL, }, { 1, 1, { identifier: "Y800 744x480", size: {0,0,744,480}, min_size: { 0,0,744,480 }, max_size: { 0,0,744,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 744 * 480, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 744 * 480, NULL, }, }; static struct euvccam_video_format_description formats_8202_mono[] = { { 1, 3, { identifier: "Y800 320x240", size: {0,0,320,240}, min_size: { 0,0,320,240 }, max_size: { 0,0,320,240 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 320 * 240, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 320 * 240, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 2, { identifier: "Y800 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 640 * 480, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 640 * 480, NULL, }, { 1, 1, { identifier: "Y800 744x480", size: {0,0,744,480}, min_size: { 0,0,744,480 }, max_size: { 0,0,744,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 744 * 480, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 744 * 480, NULL, }, }; static double format_8203_1024_framerates[] = { 60, 30, 15, 7.5}; static int format_8203_1024_framerate_map[] = { 0, 1, 2, 3}; static double format_8203_2048_framerates[] = { 60, 30, 15, 7.5}; static int format_8203_2048_framerate_map[] = { 0, 1, 2, 3}; static struct euvccam_video_format_description formats_8203_color[] = { { 1, 2, { identifier: "RGB24 1024x768", size: {0,0,1024,768}, min_size: { 0,0,1024,768 }, max_size: { 0,0,1024,768 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 1024 * 768 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8203_1024_framerates ), format_8203_1024_framerates, format_8203_1024_framerate_map, 1024 * 768, euvccam_colorproc_by8_gr_rgb24_nn, }, { 1, 1, { identifier: "RGB24 2048x1536", size: {0,0,2048,1536}, min_size: { 0,0,2048,1536 }, max_size: { 0,0,2048,1536 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 2048 * 1536 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8203_2048_framerates ), format_8203_2048_framerates, format_8203_2048_framerate_map, 2048 * 1536, euvccam_colorproc_by8_gr_rgb24_nn, }, { 1, 2, { identifier: "Y800 1024x768", size: {0,0,1024,768}, min_size: { 0,0,1024,768 }, max_size: { 0,0,1024,768 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 1024 * 768, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8203_1024_framerates ), format_8203_1024_framerates, format_8203_1024_framerate_map, 1024 * 768, NULL, }, { 1, 1, { identifier: "Y800 2048x1536", size: {0,0,2048,1536}, min_size: { 0,0,2048,1536 }, max_size: { 0,0,2048,1536 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 2048 * 1536, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8203_2048_framerates ), format_8203_2048_framerates, format_8203_2048_framerate_map, 2048 * 1536, NULL, }, }; static double format_8204_framerates[] = { 27.02, 20, 15, 7.5}; static int format_8204_framerate_map[] = { 0, 1, 2, 3}; static struct euvccam_video_format_description formats_8204_mono[] = { { 1, 2, { identifier: "Y800 1280x1024", size: {0,0,1280,1024}, min_size: { 0,0,1280,1024 }, max_size: { 0,0,1280,1024 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 1280 * 1024, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8204_framerates ), format_8204_framerates, format_8204_framerate_map, 1280 * 1024, NULL, }, { 1, 2, { identifier: "Y800 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 640 * 480, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8204_framerates ), format_8204_framerates, format_8204_framerate_map, 640 * 480, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, }; static double format_8205_framerates[] = { 30, 15, 7.5, 3.75 }; static int format_8205_framerate_map[] = { 0, 1, 2, 3 }; static struct euvccam_video_format_description formats_8205[] = { { 1, 1, { identifier: "Y800 1600x1200", size: {0,0,1600,1200}, min_size: { 0,0,1600,1200 }, max_size: { 0,0,1600,1200 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 1600 * 1200, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8205_framerates ), format_8205_framerates, format_8205_framerate_map, 1600 * 1200, NULL, }, { 1, 1, { identifier: "RGB24 1600x1200", size: {0,0,1600,1200}, min_size: { 0,0,32,32 }, max_size: { 0,0,1600,1200 }, h_stepping: 4, v_stepping: 4, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 1600 * 1200 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8205_framerates ), format_8205_framerates, format_8205_framerate_map, 1600 * 1200, euvccam_colorproc_by8_rgb24_nn, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 2, 2, { identifier: "UYVY 1024x768", size: {0,0,1024,768}, min_size: { 0,0,1024,768 }, max_size: { 0,0,1024,768 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 16, buffer_size: 1024 * 768 * 2, fourcc: FOURCC( 'U', 'Y', 'V', 'Y' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8205_framerates ), format_8205_framerates, format_8205_framerate_map, 1024 * 768 * 2, NULL, }, { 2, 4, { identifier: "UYVY 640x480", size: {0,0,640,480}, min_size: { 0,0,640,480 }, max_size: { 0,0,640,480 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 16, buffer_size: 640 * 480 * 2, fourcc: FOURCC( 'U', 'Y', 'V', 'Y' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8205_framerates ), format_8205_framerates, format_8205_framerate_map, 640 * 480 * 2, NULL, }, { 1, 1, { identifier: "YUYV 1600x1200", size: {0,0,1600,1200}, min_size: { 0,0,1600,1200 }, max_size: { 0,0,1600,1200 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 1600 * 1200 * 2, fourcc: FOURCC( 'Y', 'U', 'Y', 'V' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8205_framerates ), format_8205_framerates, format_8205_framerate_map, 1600 * 1200 * 2, NULL, }, { 1, 2, { identifier: "YUYV 1024x768", size: {0,0,1024,768}, min_size: { 0,0,1024,768 }, max_size: { 0,0,1024,768 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 1024 * 768 * 2, fourcc: FOURCC( 'Y', 'U', 'Y', 'V' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8205_framerates ), format_8205_framerates, format_8205_framerate_map, 1024 * 768 * 2, NULL, }, }; static double format_8206_framerates[] = { 30, 15, 7.5, 3.75 }; static int format_8206_framerate_map[] = { 0, 1, 2, 3 }; static struct euvccam_video_format_description formats_8206[] = { { 1, 1, { identifier: "RGB24 1280x1024", size: {0,0,1280,1024}, min_size: { 0,0,1280,1024 }, max_size: { 0,0,1280,1024 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 1280 * 1024 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 1280 * 1024, euvccam_colorproc_by8_rgb24_nn_be, }, { 1, 1, { identifier: "Y800 1280x1024", size: {0,0,1280,1024}, min_size: { 0,0,1280,1024 }, max_size: { 0,0,1280,1024 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 1280 * 1024, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8202_framerates, format_8202_framerate_map, 1280 * 1024, NULL, }, { 2, 1, { identifier: "UYVY 1280x1024", size: {0,0,1280,1024}, min_size: { 0,0,4,4 }, max_size: { 0,0,1280,1024 }, h_stepping: 4, v_stepping: 4, sizes: NULL, size_count: 0, bpp: 16, buffer_size: 1280 * 1024 * 2, fourcc: FOURCC( 'U', 'Y', 'V', 'Y' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8206_framerates ), format_8206_framerates, format_8206_framerate_map, 1280 * 1024 * 2, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 2, 2, { identifier: "UYVY 1024x768", size: {0,0,1024,768}, min_size: { 0,0,1024,768 }, max_size: { 0,0,1024,768 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 16, buffer_size: 1024 * 768 * 2, fourcc: FOURCC( 'U', 'Y', 'V', 'Y' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8206_framerates ), format_8206_framerates, format_8206_framerate_map, 1024 * 768 * 2, NULL, }, { 1, 1, { identifier: "YUYV 1280x960", size: {0,0,1280,960}, min_size: { 0,0,1280,960 }, max_size: { 0,0,1280,960 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 1280 * 960 * 2, fourcc: FOURCC( 'Y', 'U', 'Y', 'V' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8206_framerates ), format_8206_framerates, format_8206_framerate_map, 1280 * 960 * 2, NULL, }, { 1, 2, { identifier: "YUYV 1024x768", size: {0,0,1024,768}, min_size: { 0,0,1024,768 }, max_size: { 0,0,1024,768 }, h_stepping: 0, v_stepping: 0, sizes: euvccam_WVGA_sizes, size_count: N_ELEMENTS( euvccam_WVGA_sizes ), bpp: 16, buffer_size: 1024 * 768 * 2, fourcc: FOURCC( 'Y', 'U', 'Y', 'V' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8206_framerates ), format_8206_framerates, format_8206_framerate_map, 1024 * 768 * 2, NULL, }, }; static double format_8207_framerates[] = { 30, 15, 7.5, 3.75 }; static int format_8207_framerate_map[] = { 0, 1, 2, 3 }; static struct euvccam_video_format_description formats_8207_color[] = { { 1, 1, { identifier: "RGB24 2592x1944", size: {0,0,2592,1944}, min_size: { 0,0,16,16 }, max_size: { 0,0,2592,1944 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 2592 * 1944 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8207_framerates ), format_8207_framerates, format_8207_framerate_map, 2592 * 1944, euvccam_colorproc_by8_gr_rgb24_nn/* euvccam_colorproc_by8_rgb24_nn_be */, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 1, { identifier: "RGB24 2x Binning", size: {0,0,2592/2,1944/2}, min_size: { 0,0,16,16 }, max_size: { 0,0,2592/2,1944/2 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 2592/2 * 1944/2 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8207_framerates ), format_8207_framerates, format_8207_framerate_map, 2592/2 * 1944/2, euvccam_colorproc_by8_gr_rgb24_nn/* euvccam_colorproc_by8_rgb24_nn_be */, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 1, { identifier: "RGB24 4x Binning", size: {0,0,2592/4,1944/4}, min_size: { 0,0,16,16 }, max_size: { 0,0,2592/4,1944/4 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 2592/4 * 1944/4 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8207_framerates ), format_8207_framerates, format_8207_framerate_map, 2592/4 * 1944/4, euvccam_colorproc_by8_gr_rgb24_nn/* euvccam_colorproc_by8_rgb24_nn_be */, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 1, { identifier: "Y800 2592x1944", size: {0,0,2592,1944}, min_size: { 0,0,16,16 }, max_size: { 0,0,2592,1944 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 2592 * 1944, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8207_framerates, format_8207_framerate_map, 2592 * 1944, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, }; static struct euvccam_video_format_description formats_8207_mono[] = { { 1, 1, { identifier: "Y800", size: {0,0,2592,1944}, min_size: { 0,0,2592,1944 }, max_size: { 0,0,2592,1944 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 2592 * 1944, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8207_framerates, format_8207_framerate_map, 2592 * 1944, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 1, { identifier: "Y800 2x Binning", size: {0,0,2592/2,1944/2}, min_size: { 0,0,16,16 }, max_size: { 0,0,2592/2,1944/2 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 2592/2 * 1944/2, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8207_framerates ), format_8207_framerates, format_8207_framerate_map, 2592/2 * 1944/2, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 1, { identifier: "Y800 4x Binning", size: {0,0,2592/4,1944/4}, min_size: { 0,0,16,16 }, max_size: { 0,0,2592/4,1944/4 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 2592/4 * 1944/4, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8207_framerates ), format_8207_framerates, format_8207_framerate_map, 2592/4 * 1944/4, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, }; static double format_8208_framerates[] = { 30, 15, 7.5, 3.75 }; static int format_8208_framerate_map[] = { 0, 1, 2, 3 }; static struct euvccam_video_format_description formats_8208_color[] = { { 1, 1, { identifier: "RGB24 1280x960", size: {0,0,1280,960}, min_size: { 0,0,16,16 }, max_size: { 0,0,1280,960 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 24, buffer_size: 1280 * 960 * 3, fourcc: FOURCC( 'R', 'G', 'B', '3' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8207_framerates ), format_8207_framerates, format_8207_framerate_map, 1280 * 960, euvccam_colorproc_by8_gr_rgb24_nn/* euvccam_colorproc_by8_rgb24_nn_be */, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, { 1, 1, { identifier: "Y800 1280x960", size: {0,0,1280,960}, min_size: { 0,0,16,16 }, max_size: { 0,0,1280,960 }, h_stepping: 0, v_stepping: 0, sizes: NULL, size_count: 0, bpp: 8, buffer_size: 1280 * 960, fourcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_SYSTEM | UNICAP_BUFFER_TYPE_USER, system_buffer_count: EUVCCAM_SYSTEM_BUFFER_COUNT, buffer_type: 0 }, N_ELEMENTS( format_8202_framerates ), format_8207_framerates, format_8207_framerate_map, 1280 * 960, NULL, EUVCCAM_FORMAT_IS_PARTIAL_SCAN, }, }; struct euvccam_devspec euvccam_devspec[] = { { 0x8201, 0, 0, N_ELEMENTS( formats_8201 ), formats_8201, N_ELEMENTS( properties_8201 ), properties_8201, }, { 0x8202, 1, 0, N_ELEMENTS( formats_8202_mono ), formats_8202_mono, N_ELEMENTS( properties_8202_mono ), properties_8202_mono, }, { 0x8202, 2, 0, N_ELEMENTS( formats_8202_color ), formats_8202_color, N_ELEMENTS( properties_8202_color ), properties_8202_color, }, { 0x8203, 6, 0, N_ELEMENTS( formats_8203_color ), formats_8203_color, N_ELEMENTS( properties_8202_color ), properties_8202_color, }, { 0x8204, (2<<2)|1, 0, N_ELEMENTS( formats_8204_mono ), formats_8204_mono, N_ELEMENTS( properties_8202_mono ), properties_8202_mono, }, { 0x8205, (3<<2)|1, 0, N_ELEMENTS( formats_8205 ), formats_8205, N_ELEMENTS( properties_8201 ), properties_8201, }, { 0x8206, (4<<2), 0, N_ELEMENTS( formats_8206 ), formats_8206, N_ELEMENTS( properties_8206 ), properties_8206, }, { 0x8207, (5<<2)|2, 0, N_ELEMENTS( formats_8207_color ), formats_8207_color, N_ELEMENTS( properties_8206 ), properties_8206, }, { 0x8207, (5<<2)|1, 0, N_ELEMENTS( formats_8207_mono ), formats_8207_mono, N_ELEMENTS( properties_8206 ), properties_8206, }, { 0x8208, (6<<2)|2, 0, N_ELEMENTS( formats_8208_color ), formats_8208_color, N_ELEMENTS( properties_8206 ), properties_8206, }, { 0, } }; libunicap/cpi/euvccam/debayer.h0000644000175000017500000000345713164711411017250 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software */ #ifndef __DEBAYER_H__ #define __DEBAYER_H__ enum{ WB_MODE_MANUAL = 0, WB_MODE_AUTO, WB_MODE_ONE_PUSH }; struct _debayer_data { int use_ccm; int use_rbgain; int wb_auto_mode; // Color Correction Matrix int ccm[3][3]; // red / blue gain int rgain; int bgain; }; typedef struct _debayer_data debayer_data_t; void debayer_ccm_rgb24_nn( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ); void debayer_ccm_rgb24_gr_nn( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ); void debayer_ccm_rgb24_edge( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ); void debayer_ccm_uyvy( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ); void debayer_calculate_rbgain( unicap_data_buffer_t *buffer, int *rgain, int *bgain, int *combined ); void debayer_ccm_rgb24_nn_be( unicap_data_buffer_t *destbuf, unicap_data_buffer_t *srcbuf, debayer_data_t *data ); void debayer_sse2( unicap_data_buffer_t *destbuf, unicap_data_buffer_t* srcbuf, debayer_data_t *data ); #endif//__DEBAYER_H__ libunicap/cpi/euvccam/euvccam_colorproc.c0000644000175000017500000000753213164711411021333 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "euvccam_cpi.h" #include "debayer.h" void euvccam_colorproc_by8_rgb24_nn( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ) { #ifdef __SSE2__ debayer_sse2( dest, src, &handle->debayer_data ); #else debayer_ccm_rgb24_nn( dest, src, &handle->debayer_data ); #endif } void euvccam_colorproc_by8_rgb24_nn_be( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ) { debayer_ccm_rgb24_nn_be( dest, src, &handle->debayer_data ); } void euvccam_colorproc_by8_gr_rgb24_nn( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ) { debayer_ccm_rgb24_gr_nn( dest, src, &handle->debayer_data ); } void euvccam_colorproc_by8_sse2( euvccam_handle_t handle, unicap_data_buffer_t *dest, unicap_data_buffer_t *src ) { #ifdef __SSE2__ debayer_sse2( dest, src, &handle->debayer_data ); #else debayer_ccm_rgb24_nn( dest, src, &handle->debayer_data ); #endif } unicap_status_t euvccam_colorproc_set_wbgain( euvccam_handle_t handle, unicap_property_t *property ) { if( !strcmp( property->identifier, "White Balance Blue" ) ){ handle->debayer_data.bgain = property->value * 4096.0; } else { handle->debayer_data.rgain = property->value * 4096.0; } return STATUS_SUCCESS; } unicap_status_t euvccam_colorproc_get_wbgain( euvccam_handle_t handle, unicap_property_t *property ) { if( !strcmp( property->identifier, "White Balance Blue" ) ){ property->value = handle->debayer_data.bgain / 4096.0; }else{ property->value = handle->debayer_data.rgain / 4096.0; } return STATUS_SUCCESS; } unicap_status_t euvccam_colorproc_set_wbgain_mode( euvccam_handle_t handle, unicap_property_t *property ) { if( property->flags & UNICAP_FLAGS_AUTO ) handle->debayer_data.wb_auto_mode = WB_MODE_AUTO; else if( property->flags & UNICAP_FLAGS_ONE_PUSH ) handle->debayer_data.wb_auto_mode = WB_MODE_ONE_PUSH; else handle->debayer_data.wb_auto_mode = WB_MODE_MANUAL; return STATUS_SUCCESS; } unicap_status_t euvccam_colorproc_get_wbgain_mode( euvccam_handle_t handle, unicap_property_t *property ) { switch( handle->debayer_data.wb_auto_mode ){ case WB_MODE_AUTO: property->flags = UNICAP_FLAGS_AUTO; break; case WB_MODE_ONE_PUSH: property->flags = UNICAP_FLAGS_ONE_PUSH; break; default: property->flags = UNICAP_FLAGS_MANUAL; break; } return STATUS_SUCCESS; } void euvccam_colorproc_auto_wb( euvccam_handle_t handle, unicap_data_buffer_t *buffer ) { int x,y; const int step = 32; unsigned int rval = 0, bval = 0, gval = 0; for( y = step; y < buffer->format.size.height - step; y+=step ){ int lineoffset = y * buffer->format.size.width; for( x = step; x < buffer->format.size.width - step; x+=step ){ gval += buffer->data[ lineoffset + x ]; bval += buffer->data[ lineoffset + x + 1]; rval += buffer->data[ lineoffset + buffer->format.size.width + x ]; } } handle->debayer_data.rgain = ( (double)gval / (double)rval ) * 4096; handle->debayer_data.bgain = ( (double)gval / (double)bval ) * 4096; } libunicap/cpi/euvccam/euvccam_device.c0000644000175000017500000007254013164711411020571 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "euvccam_cpi.h" #include "euvccam_device.h" #include "euvccam_capture.h" #include "euvccam_devspec.h" #include "euvccam_usb.h" #define EUVCCAM_VENDOR_ID 0x199e #define N_ELEMENTS(a) (sizeof( a )/ sizeof(( a )[0] )) #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #define SET_CUR 0x01 #define GET_CUR 0x81 #define GET_DEF 0x87 #define VS_PROBE_CONTROL 0x01 #define VS_COMMIT_CONTROL 0x02 #define SC_VIDEOSTREAMING 0x02 #define CT_AE_MODE_CONTROL 0x02 #define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 #define CT_PRIVACY_CONTROL 0x11 #define CT_TIS_PIXEL_CLOCK 0x24 #define CT_TIS_PARTIAL_SCAN_WIDTH 0x25 #define CT_TIS_PARTIAL_SCAN_HEIGHT 0x26 #define CT_TIS_BINNING 0x2a #define CT_TIS_SOFTWARE_TRIGGER 0x2b #define CT_TIS_SENSOR_RESET 0x2c #define CT_TIS_FIRMWARE_REVISION 0x2d #define CT_TIS_GPOUT 0x2e #define CT_TIS_HDR_ENABLE 0x2f #define CT_TIS_HDR_SHUTTER_1 0x30 #define CT_TIS_HDR_SHUTTER_2 0x31 #define CT_TIS_HDR_VSTEP_1 0x32 #define CT_TIS_HDR_VSTEP_2 0x33 #define CT_TIS_HDR_VSTEP_3 0x34 #define CT_TIS_HDR_VSTEP_4 0x35 #define CT_TIS_UART 0x41 #define PU_GAIN_CONTROL 0x04 #define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c #define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d #define PU_TIS_COLOR_FORMAT 0x21 #define CAMERA_TERMINAL 1 #define PROCESSING_UNIT 3 #define COLOR_FORMAT_MONO8 0 #define COLOR_FORMAT_UYVY 1 #define COLOR_FORMAT_BAYER1 3 /* static unsigned long long euvccam_usb_string_to_number( char *string ); */ unicap_status_t euvccam_read_vendor_register( int fd, int index, unsigned char *val ) { unsigned char length = 1; unicap_status_t status = STATUS_SUCCESS; status = euvccam_usb_ctrl_msg(fd, EP0_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0, // UVCD Register Request 0x0, index, (char*)val, length); return status; } unicap_status_t euvccam_write_vendor_register( int fd, int index, unsigned char val ) { unicap_status_t status = STATUS_SUCCESS; status = euvccam_usb_ctrl_msg(fd, EP0_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0, // UVCD Register Request 0x0, index, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_format( euvccam_handle_t handle, euvccam_video_format_description_t **format ) { unicap_status_t status = STATUS_SUCCESS; struct probe_control probe; unsigned short val; int i; memset( &probe, 0x0, sizeof( struct probe_control ) ); status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_DEF, VS_PROBE_CONTROL << 8, 1, (char*)&probe, sizeof( probe )); if( !SUCCESS( status ) ){ TRACE( "probe control failed!\n" ); return STATUS_FAILURE; } for( i = 0; i < euvccam_devspec[handle->devspec_index].format_count; i++ ){ if( ( probe.bFormatIndex == euvccam_devspec[handle->devspec_index].format_list[i].format_index ) && ( probe.bFrameIndex == euvccam_devspec[handle->devspec_index].format_list[i].frame_index ) ){ *format = &euvccam_devspec[handle->devspec_index].format_list[i]; break; } } if( i == euvccam_devspec[handle->devspec_index].format_count ){ TRACE( "Invalid format returned by camera! FormatIndex = %d FrameIndex = %d\n", probe.bFormatIndex, probe.bFrameIndex ); *format = &euvccam_devspec[handle->devspec_index].format_list[0]; } status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_PARTIAL_SCAN_WIDTH << 8, CAMERA_TERMINAL << 8, (char*)&val, 2 ); if( ( val >= (*format)->format.min_size.width ) && ( val <= (*format)->format.max_size.width ) ){ (*format)->format.size.width = val; } status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_PARTIAL_SCAN_HEIGHT << 8, CAMERA_TERMINAL << 8, (char*)&val, 2 ); if( ( val >= (*format)->format.min_size.height ) && ( val <= (*format)->format.max_size.height ) ){ (*format)->format.size.height = val; } return status; } unicap_status_t euvccam_device_set_format( euvccam_handle_t handle, unicap_format_t *format ) { unicap_status_t status = STATUS_SUCCESS; struct probe_control commit; int i; int old_capture = handle->capture_running; struct euvccam_video_format_description *dscr = NULL; unsigned short cf = COLOR_FORMAT_UYVY; unsigned char binning = 1; if( old_capture ) euvccam_capture_stop_capture( handle ); memset( &commit, 0x0, sizeof( struct probe_control ) ); for( i = 0; i < euvccam_devspec[handle->devspec_index].format_count; i++ ){ struct euvccam_video_format_description *tmp = &euvccam_devspec[handle->devspec_index].format_list[i]; if( ( tmp->format.size.width <= format->max_size.width ) && ( tmp->format.size.height <= format->max_size.height ) && ( tmp->format.size.width >= format->min_size.width ) && ( tmp->format.size.height >= format->min_size.height ) && ( tmp->format.fourcc == format->fourcc ) ){ commit.bFormatIndex = tmp->format_index; commit.bFrameIndex = tmp->frame_index; dscr = tmp; break; } } if( !dscr ){ TRACE( "No match for format: %dx%d %s\n", format->size.width, format->size.height, format->identifier ); return STATUS_NO_MATCH; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, VS_COMMIT_CONTROL<<8, 1, (char*)&commit, sizeof( commit )); usleep( 100000 ); if( dscr->flags & EUVCCAM_FORMAT_IS_PARTIAL_SCAN ){ unsigned short val = format->size.width; TRACE( "partial scan %dx%d\n", format->size.width, format->size.height ); /* status = euvccam_usb_ctrl_msg( handle->dev.fd, */ /* EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, */ /* SET_CUR, */ /* CT_AE_MODE_CONTROL << 8, */ /* CAMERA_TERMINAL << 8, */ /* &handle->current_ae_mode, 1); */ status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_PARTIAL_SCAN_WIDTH << 8, CAMERA_TERMINAL << 8, (char*)&val, 2 ); TRACE( "Set partial scan width: %d\n", status ); val = format->size.height; status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_PARTIAL_SCAN_HEIGHT << 8, CAMERA_TERMINAL << 8, (char*)&val, 2 ); TRACE( "Set partial scan height: %d\n", status ); } switch( format->fourcc ){ case FOURCC( 'U', 'Y', 'V', 'Y' ): cf = COLOR_FORMAT_UYVY; break; case FOURCC( 'R', 'G', 'B', '3' ): cf = COLOR_FORMAT_BAYER1; break; } if( strstr( format->identifier, "2x Binning" ) ){ binning = 2; } if( strstr( format->identifier, "4x Binning" ) ){ binning = 4; } euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_BINNING << 8, CAMERA_TERMINAL << 8, (char *)&binning, 1 ); TRACE( "Binning: %d\n", binning ); TRACE( "cf: %d\n", cf ); //status |= euvccam_usb_ctrl_msg( handle->dev.fd, // EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, // SET_CUR, // PU_TIS_COLOR_FORMAT << 8, // PROCESSING_UNIT << 8, // (char*)&cf, 2 ); if( SUCCESS( status ) ){ handle->current_format = dscr; handle->current_format->format.size.width = format->size.width; handle->current_format->format.size.height = format->size.height; } if( old_capture ) euvccam_capture_start_capture( handle ); return status; } unicap_status_t euvccam_device_set_reset_mt9v024( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status; unsigned char val = 1; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_SENSOR_RESET << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_reset_mt9v024( euvccam_handle_t handle, unicap_property_t *property ) { return STATUS_SUCCESS; } unicap_status_t euvccam_device_write_iic( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status; if( property->property_data_size < sizeof( struct euvccam_iic_command ) ){ return STATUS_INVALID_PARAMETER; } struct euvccam_iic_command *iiccmd = ( struct euvccam_iic_command * )property->property_data; // set IIC device address euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE, SET_CUR, 0x40 << 8, 0x1 << 8, &iiccmd->devaddr, 1 ); // set IIC address status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE, SET_CUR, 0x21 << 8, 0x1 << 8, &iiccmd->addr, 1 ); // write IIC value status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE, SET_CUR, 0x22 << 8, 0x1 << 8, &iiccmd->value, 2 ); return status; } unicap_status_t euvccam_device_read_iic( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status; static unsigned char devaddr = 0xff; if( property->property_data_size < sizeof( struct euvccam_iic_command ) ){ return STATUS_INVALID_PARAMETER; } struct euvccam_iic_command *iiccmd = ( struct euvccam_iic_command * )property->property_data; if( devaddr != iiccmd->devaddr ){ // set IIC device address euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE, SET_CUR, 0x40 << 8, 0x1 << 8, &iiccmd->devaddr, 1 ); devaddr = iiccmd->devaddr; } // set IIC address status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE, SET_CUR, 0x21 << 8, 0x1 << 8, &iiccmd->addr, 1 ); // read IIC value status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE, GET_CUR, 0x22 << 8, 0x1 << 8, &iiccmd->value, 2 ); return status; } unicap_status_t euvccam_device_set_exposure( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val = property->value * 10000.0; char old_ae_mode = handle->current_ae_mode; if( property->flags & UNICAP_FLAGS_AUTO ){ handle->current_ae_mode |= 1<<1; }else{ handle->current_ae_mode &= ~(1<<1); } if( (euvccam_devspec[handle->devspec_index].flags & EUVCCAM_HAS_AUTO_EXPOSURE ) && ( old_ae_mode != handle->current_ae_mode ) ){ status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_AE_MODE_CONTROL << 8, CAMERA_TERMINAL << 8, &handle->current_ae_mode, 1); } status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8, CAMERA_TERMINAL << 8, (char*)&val, 4); TRACE( "set_exposure va: %d\n", val ); return status; } unicap_status_t euvccam_device_get_exposure( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val; if( euvccam_devspec[handle->devspec_index].flags & EUVCCAM_HAS_AUTO_EXPOSURE ){ status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_AE_MODE_CONTROL << 8, CAMERA_TERMINAL << 8, &handle->current_ae_mode, 1); } if( handle->current_ae_mode & ( 1<<1 ) ){ property->flags = UNICAP_FLAGS_AUTO; }else{ property->flags = UNICAP_FLAGS_MANUAL; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8, CAMERA_TERMINAL << 8, (char*)&val, 4); property->value = (double)val / 10000.0; return status; } unicap_status_t euvccam_device_set_gain( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val = property->value; char old_ae_mode = handle->current_ae_mode; if( property->flags & UNICAP_FLAGS_AUTO ){ handle->current_ae_mode |= 1<<2; }else{ handle->current_ae_mode &= ~(1<<2); } if( (euvccam_devspec[handle->devspec_index].flags & EUVCCAM_HAS_AUTO_GAIN ) && ( old_ae_mode != handle->current_ae_mode ) ){ status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_AE_MODE_CONTROL << 8, CAMERA_TERMINAL << 8, &handle->current_ae_mode, 1); } status |= euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, PU_GAIN_CONTROL << 8, PROCESSING_UNIT << 8, (char*)&val, 4); return status; } unicap_status_t euvccam_device_get_gain( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val; if( euvccam_devspec[handle->devspec_index].flags & EUVCCAM_HAS_AUTO_GAIN ){ status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_AE_MODE_CONTROL << 8, CAMERA_TERMINAL << 8, &handle->current_ae_mode, 1); } if( handle->current_ae_mode & ( 1<<2 ) ){ property->flags = UNICAP_FLAGS_AUTO; }else{ property->flags = UNICAP_FLAGS_MANUAL; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, PU_GAIN_CONTROL << 8, PROCESSING_UNIT << 8, (char*)&val, 4); property->value = val; return status; } unicap_status_t euvccam_device_set_white_balance( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val = 0; if( !strcmp( property->identifier, "White Balance Red" ) ){ val &= 0xffff; val |= ((int)property->value) << 16; }else{ val &= 0xffff0000; val |= ((int)property->value) & 0xffff; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, PU_WHITE_BALANCE_COMPONENT_CONTROL << 8, PROCESSING_UNIT << 8, (char*)&val, 4); return status; } unicap_status_t euvccam_device_get_white_balance( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, PU_WHITE_BALANCE_COMPONENT_CONTROL << 8, PROCESSING_UNIT << 8, (char*)&val, 4); if( !strcmp( property->identifier, "White Balance Red" ) ){ property->value = ( val >> 16 ) & 0xffff; } else { property->value = val & 0xffff; } return status; } unicap_status_t euvccam_device_set_white_balance_mode( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = 0; if( property->flags & UNICAP_FLAGS_AUTO ){ val = 1; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL << 8, PROCESSING_UNIT << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_white_balance_mode( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, PU_WHITE_BALANCE_COMPONENT_CONTROL << 8, PROCESSING_UNIT << 8, (char*)&val, 1); if( val ){ property->flags = UNICAP_FLAGS_AUTO; }else{ property->flags = UNICAP_FLAGS_MANUAL; } return status; } unicap_status_t euvccam_device_set_trigger( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = 0; if( strcmp( property->menu_item, "free running" ) ){ val = 1; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_PRIVACY_CONTROL << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_trigger( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_PRIVACY_CONTROL << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); TRACE( "trigger val: %d\n", val ); if( val ){ strcpy( property->menu_item, "trigger on rising edge" ); }else{ strcpy( property->menu_item, "free running" ); } return status; } unicap_status_t euvccam_device_enumerate_trigger( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( SUCCESS( euvccam_device_get_trigger( handle, property ) ) ){ status = STATUS_SUCCESS; } return status; } unicap_status_t euvccam_device_set_software_trigger( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = 1; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_SOFTWARE_TRIGGER << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_software_trigger( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_SOFTWARE_TRIGGER << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); TRACE( "Get software trigger: %d\n", val ); return status; } unicap_status_t euvccam_device_enumerate_software_trigger( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( SUCCESS( euvccam_device_get_trigger( handle, property ) ) ){ status = STATUS_SUCCESS; } return status; } unicap_status_t euvccam_device_set_frame_rate( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char regval = 0; int i; for( i = 0; i < handle->current_format->frame_rate_count; i++ ){ if( handle->current_format->frame_rates[i] == property->value ){ regval = handle->current_format->frame_rate_map[i]; } } printf ("fr: %f reg: %d\n", property->value, regval); property->value_list.values = handle->current_format->frame_rates; property->value_list.value_count = handle->current_format->frame_rate_count; status = euvccam_write_vendor_register( handle->dev.fd, 0x3a, regval ); return status; } unicap_status_t euvccam_device_get_frame_rate( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char regval; double val = 0.0; if( !handle->current_format ){ return STATUS_FAILURE; } status = euvccam_read_vendor_register( handle->dev.fd, 0x3a, ®val ); if( SUCCESS( status ) ){ int i; for( i = 0; i < handle->current_format->frame_rate_count; i++ ){ if( handle->current_format->frame_rate_map[i] == regval ){ val = handle->current_format->frame_rates[i]; } } } property->value_list.values = handle->current_format->frame_rates; property->value_list.value_count = handle->current_format->frame_rate_count; property->value = val; return status; } unicap_status_t euvccam_device_enumerate_frame_rate( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status; status = euvccam_device_get_frame_rate( handle, property ); if( SUCCESS( status ) ){ property->value = handle->current_format->frame_rates[0]; } return status; } unicap_status_t euvccam_device_set_pixel_clock( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val = property->value * 1000000.0; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_PIXEL_CLOCK << 8, CAMERA_TERMINAL << 8, (char*)&val, 4); return status; } unicap_status_t euvccam_device_get_pixel_clock( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned int val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_PIXEL_CLOCK << 8, CAMERA_TERMINAL << 8, (char*)&val, 4); property->value = (double)val / 1000000.0; return status; } unicap_status_t euvccam_device_set_gpout( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = (property->flags & UNICAP_FLAGS_ON_OFF)?1:0; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_GPOUT << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_gpout( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_GPOUT << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); property->flags = UNICAP_FLAGS_MANUAL | ( val ? UNICAP_FLAGS_ON_OFF : 0); return status; } unicap_status_t euvccam_device_enumerate_gpout( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( SUCCESS( euvccam_device_get_gpout( handle, property ) ) ){ status = STATUS_SUCCESS; } return status; } unicap_status_t euvccam_device_enable_hdr (euvccam_handle_t handle, unicap_property_t *property) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = (property->flags & UNICAP_FLAGS_ON_OFF)?1:0; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_HDR_ENABLE << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_enable_hdr (euvccam_handle_t handle, unicap_property_t *property) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_HDR_ENABLE << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); property->flags = UNICAP_FLAGS_MANUAL | ( val ? UNICAP_FLAGS_ON_OFF : 0); return status; } unicap_status_t euvccam_device_enumerate_hdr( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( SUCCESS( euvccam_device_get_enable_hdr( handle, property ) ) ){ status = STATUS_SUCCESS; } return status; } unicap_status_t euvccam_device_set_hdr_shutter (euvccam_handle_t handle, unicap_property_t *property) { unicap_status_t status = STATUS_SUCCESS; unsigned int val = property->value * 10000.0; int function = 0; if (property->identifier[strlen(property->identifier)-1] == '1'){ function = CT_TIS_HDR_SHUTTER_1; } else { function = CT_TIS_HDR_SHUTTER_2; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, function << 8, CAMERA_TERMINAL << 8, (char*)&val, 4); return status; } unicap_status_t euvccam_device_get_hdr_shutter (euvccam_handle_t handle, unicap_property_t *property) { unicap_status_t status = STATUS_SUCCESS; unsigned int val; int function = 0; if (property->identifier[strlen(property->identifier)-1] == '1'){ function = CT_TIS_HDR_SHUTTER_1; } else { function = CT_TIS_HDR_SHUTTER_2; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, function << 8, CAMERA_TERMINAL << 8, (char*)&val, 4); property->value = (double)val / 10000.0; return status; } unicap_status_t euvccam_device_set_hdr_vstep( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = property->value; unsigned char function; switch (property->identifier[strlen(property->identifier)-1]){ case '1': function = CT_TIS_HDR_VSTEP_1; break; case '2': function = CT_TIS_HDR_VSTEP_2; break; case '3': function = CT_TIS_HDR_VSTEP_3; break; case '4': function = CT_TIS_HDR_VSTEP_4; break; default: TRACE ("Invalid parameter in HDR vstep\n"); return STATUS_INVALID_PARAMETER; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, function << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } unicap_status_t euvccam_device_get_hdr_vstep( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; unsigned char function; switch (property->identifier[strlen(property->identifier)-1]){ case '1': function = CT_TIS_HDR_VSTEP_1; break; case '2': function = CT_TIS_HDR_VSTEP_2; break; case '3': function = CT_TIS_HDR_VSTEP_3; break; case '4': function = CT_TIS_HDR_VSTEP_4; break; default: TRACE ("Invalid parameter in HDR vstep\n"); return STATUS_INVALID_PARAMETER; } status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, function << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); property->value = val; return status; } unicap_status_t euvccam_device_set_uart (euvccam_handle_t handle, unicap_property_t *property) { unicap_status_t status = STATUS_SUCCESS; unsigned char *val = property->property_data; if ((property->property_data_size <= 0) || (property->property_data_size > 8 )) return STATUS_INVALID_PARAMETER; printf ("send: '%s' %d\n", val, property->property_data_size); status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, CT_TIS_UART << 8, CAMERA_TERMINAL << 8, (char*)val, property->property_data_size); return status; } unicap_status_t euvccam_device_get_uart( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; unsigned char val; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, GET_CUR, CT_TIS_UART << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); property->value = val; return status; } unicap_status_t euvccam_device_enumerate_uart( euvccam_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if (SUCCESS (euvccam_device_get_uart (handle, property))){ status = STATUS_SUCCESS; } return status; } unicap_status_t euvccam_device_set_test (euvccam_handle_t handle, unicap_property_t *property) { unicap_status_t status = STATUS_SUCCESS; unsigned char val = property->value; status = euvccam_usb_ctrl_msg( handle->dev.fd, EP0_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, SET_CUR, 0x50 << 8, CAMERA_TERMINAL << 8, (char*)&val, 1); return status; } libunicap/cpi/euvccam/euvccam_usb.h0000644000175000017500000000454013164711411020123 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __EUVCCAM_USB_H__ #define __EUVCCAM_USB_H__ #include #include #define EP0_IN 0x80 #define EP0_OUT 0x00 #define USB_TYPE_CLASS (0x01 << 5) #define USB_TYPE_VENDOR (0x02 << 5) #define USB_RECIP_DEVICE 0x00 #define USB_RECIP_INTERFACE 0x01 #define USB_RECIP_ENDPOINT 0x02 #define GET_DESCRIPTOR 0x06 #define DT_STRING 0x03 struct euvccam_usb_device { int fd; unsigned short idProduct; unsigned short idVendor; char strProduct[64]; char strVendor[64]; char strSerialNumber[64]; char devpath[PATH_MAX +1]; char identifier[128]; unsigned long long serial; }; typedef struct euvccam_usb_device euvccam_usb_device_t; struct _usb_device_descriptor { uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; uint8_t bDeviceClass; uint8_t bDeviceSubClass; uint8_t bDeviceProtocol; uint8_t bMaxPacketSize0; uint16_t idVendor; uint16_t idProduct; uint16_t bcdDevice; uint8_t iManufacturer; uint8_t iProduct; uint8_t iSerialNumber; uint8_t bNumConfigurations; } __attribute__ ((packed)); typedef struct _usb_device_descriptor usb_device_descriptor_t; unicap_status_t euvccam_usb_init( void ); euvccam_usb_device_t *euvccam_usb_find_device( int index ); unicap_status_t euvccam_usb_open_device( unicap_device_t *unicap_device, euvccam_usb_device_t *dev ); unicap_status_t euvccam_usb_close_device( euvccam_usb_device_t *dev ); unicap_status_t euvccam_usb_ctrl_msg( int fd, uint8_t reqtype, uint8_t req, uint16_t val, uint16_t index, void *buf, uint16_t size ); #endif //__EUVCCAM_USB_H__ libunicap/cpi/euvccam/euvccam_usb.c0000644000175000017500000002124113164711411020113 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include "euvccam_cpi.h" #include "euvccam_usb.h" #ifdef DEBUG #include #endif #define N_ELEMENTS(x) (sizeof(x)/sizeof(x[0])) static char *usb_path = NULL; static char *usb_search_path[]= { "/dev/bus/usb", "/proc/bus/usb", NULL }; static uint16_t supported_pids[] = { 0x8201, 0x8202, 0x8203, 0x8204, 0x8205, 0x8206, 0x8207, 0x8208 }; static char *get_usb_path( void ) { int i; char *path = NULL; for( i = 0; (path == NULL) && usb_search_path[i]; i++ ){ DIR *dir = opendir( usb_search_path[i] ); if( dir ){ struct dirent *dirent; while(( dirent = readdir( dir ) ) != NULL ){ if( dirent->d_name[0] == '.' ){ path = usb_search_path[i]; break; } } closedir( dir ); } } return path; } static int is_supported( uint16_t vid, uint16_t pid ) { TRACE( "vid = %x, pid = %x\n", vid, pid ); if( vid == 0x199e ){ int i; for( i = 0; i < N_ELEMENTS( supported_pids ); i++ ){ if( supported_pids[i] == pid ) return 1; } } return 0; } static unsigned long long string_to_number( char *string ) { int i; unsigned long long ret = 0; for( i = 0; string[i]; i++ ){ if( !isdigit(string[i]) ){ return 0; } ret = (ret<<8) | (string[i]-'0'); } return ret; } static unicap_status_t claim_device( int fd ) { int tmp; unicap_status_t status = STATUS_SUCCESS; tmp = 1; if( ioctl( fd, USBDEVFS_SETCONFIGURATION, &tmp ) < 0 ) status = STATUS_FAILURE; tmp = 0; if( ioctl( fd, USBDEVFS_CLAIMINTERFACE, &tmp ) < 0 ) status = STATUS_FAILURE; tmp = 1; if( ioctl( fd, USBDEVFS_CLAIMINTERFACE, &tmp ) < 0 ) status = STATUS_FAILURE; return status; } unicap_status_t euvccam_usb_init( void ) { if( usb_path ){ TRACE( "EUVCCAM_USB already initialized\n" ); return STATUS_FAILURE; } usb_path = get_usb_path(); TRACE( "euvccam_usb_init - usb_path = %s\n", usb_path ); return ( usb_path != NULL ) ? STATUS_SUCCESS : STATUS_FAILURE; } void print_caller( int depth ) { #ifdef DEBUG void *array[10]; size_t size; char **strings; size_t i; size = backtrace (array, 10); strings = backtrace_symbols (array, size); if( size > depth ){ printf ("%s\n", strings[depth ]); } free (strings); #else return; #endif } unicap_status_t euvccam_usb_ctrl_msg( int fd, uint8_t reqtype, uint8_t req, uint16_t val, uint16_t index, void *buf, uint16_t size ) { struct usbdevfs_ctrltransfer xfer; int ret; unicap_status_t status = STATUS_SUCCESS; struct timespec start, end; xfer.bRequestType = reqtype; xfer.bRequest = req; xfer.wValue = val; xfer.wIndex = index; xfer.wLength = size; xfer.data = buf; xfer.timeout = 10000; TRACE( "ctrl msg: %x %x %x %x %x ::", reqtype, req, val, index, size ); print_caller( 2 ); clock_gettime (CLOCK_MONOTONIC, &start); ret = ioctl( fd, USBDEVFS_CONTROL, &xfer ); if( ret<0 ){ TRACE( "control message failed!\n" ); status = STATUS_FAILURE; } clock_gettime (CLOCK_MONOTONIC, &end); end.tv_sec -= start.tv_sec; end.tv_nsec -= start.tv_nsec; if (end.tv_nsec < 0) { end.tv_sec--; end.tv_nsec += 1000000000; } TRACE ("ctrl:: %lu.%06lu secs\n", end.tv_sec, end.tv_nsec / 1000); return status; } static unicap_status_t euvccam_usb_read_ascii_string( int fd, int index, char *buf, size_t len ) { char unicode[256]; int i,j; if( !SUCCESS( euvccam_usb_ctrl_msg( fd, EP0_IN, GET_DESCRIPTOR, (DT_STRING << 8) + index, 0, unicode, sizeof( unicode ) ) ) ){ TRACE( "Failed to read string descriptor" ); return STATUS_FAILURE; } if( unicode[1] != DT_STRING ) return STATUS_FAILURE; if( unicode[0] > ((len-1)*2) ) return STATUS_FAILURE; for( i = 0, j = 2; j < unicode[0]; i++, j+=2 ) buf[i] = unicode[j]; buf[i] = 0; return STATUS_SUCCESS; } euvccam_usb_device_t *euvccam_usb_find_device( int index ) { DIR *usbdir = opendir( usb_path ); int cind = -1; static euvccam_usb_device_t dev; euvccam_usb_device_t *ret = NULL; TRACE( "euvccam_usb_find_device index=%d\n", index ); if( usbdir ){ struct dirent *usbdirent; while((cind != index) && ((usbdirent = readdir( usbdir )) != NULL )){ if( usbdirent->d_name[0] == '.' ) continue; char buspath[PATH_MAX + 1]; sprintf( buspath, "%s/%s", usb_path, usbdirent->d_name ); TRACE( "buspath: %s\n", buspath ); DIR *busdir = opendir( buspath ); if( busdir ){ struct dirent *busdirent; while((cind != index) && ((busdirent = readdir( busdir )) != NULL )){ if( busdirent->d_name[0] == '.' ) continue; char devpath[PATH_MAX + 1]; int fd; sprintf( devpath, "%s/%s", buspath, busdirent->d_name ); fd = open( devpath, O_RDWR, 0 ); if( fd < 0 ) continue; usb_device_descriptor_t descriptor; int rd = read( fd, (void*)&descriptor, sizeof( descriptor ) ); if( rd < 0 ){ TRACE( "Failed to read descriptor for device: %s\n", devpath ); close( fd ); continue; } TRACE( "Read descriptor of device: %s len=%d\n", devpath, rd ); if( is_supported( descriptor.idVendor, descriptor.idProduct ) ){ cind++; if( cind == index ){ dev.idVendor = descriptor.idVendor; dev.idProduct = descriptor.idProduct; dev.fd = -1; if( !SUCCESS( euvccam_usb_read_ascii_string( fd, descriptor.iManufacturer, dev.strVendor, sizeof( dev.strVendor ) ) ) || !strcmp (dev.strVendor, "\t") ){ strcpy( dev.strVendor, "The Imaging Source" ); } if( !SUCCESS( euvccam_usb_read_ascii_string( fd, descriptor.iProduct, dev.strProduct, sizeof( dev.strProduct ) ) ) || !strcmp (dev.strProduct, "\t") ){ strcpy( dev.strProduct, "CMOS camera" ); } if( !SUCCESS( euvccam_usb_read_ascii_string( fd, descriptor.iSerialNumber, dev.strSerialNumber, sizeof( dev.strSerialNumber ) ) ) || !strcmp (dev.strSerialNumber, "\t") ){ strcpy( dev.strSerialNumber, "0" ); } strcpy( dev.devpath, devpath ); sprintf( dev.identifier, "%s %s %s", dev.strVendor, dev.strProduct, dev.strSerialNumber ); dev.serial = string_to_number( dev.strSerialNumber ); ret = &dev; TRACE( "Device found %x:%x\n", dev.idVendor, dev.idProduct ); } } close( fd ); } closedir( busdir ); } } closedir( usbdir ); } return ret; } unicap_status_t euvccam_usb_open_device( unicap_device_t *unicap_device, euvccam_usb_device_t *dev ) { int i; unicap_status_t status = STATUS_FAILURE; euvccam_usb_device_t *tmp = NULL; for( i = 0; ( tmp = euvccam_usb_find_device( i ) ); i++ ){ if( !strcmp( tmp->identifier, unicap_device->identifier ) ){ memcpy( dev, tmp, sizeof( euvccam_usb_device_t ) ); dev->fd = open( dev->devpath, O_RDWR, 0 ); if( dev->fd < 0 ){ TRACE( "Failed to open device: %s\n", unicap_device->identifier ); return STATUS_FAILURE; } claim_device( dev->fd ); strcpy( unicap_device->vendor_name, dev->strVendor ); strcpy( unicap_device->model_name, dev->strProduct ); unicap_device->vendor_id = dev->idVendor; unicap_device->model_id = string_to_number( dev->strSerialNumber ); strcpy( unicap_device->device, dev->devpath ); unicap_device->flags = 0; status = STATUS_SUCCESS; break; } } return status; } unicap_status_t euvccam_usb_close_device( euvccam_usb_device_t *dev ) { unicap_status_t status = STATUS_FAILURE; if( dev->fd >= 0 ){ close( dev->fd ); dev->fd = -1; status = STATUS_SUCCESS; } return status; } libunicap/cpi/euvccam/logging.h0000644000175000017500000000205113164711411017250 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LOGGING__ #define __LOGGING__ #define LOG_MODULE_CAPTURE 2 #define LOG_MODULE_USB 3 #define LOG_MODULE_DEVICE 4 #define LOG_MODULE_ANY 1 void log_init( void ); void log_close( void ); void log_message( int module, int log_level, const char *format, ... ); #endif//__LOGGING__ libunicap/cpi/euvccam/logging.c0000644000175000017500000000337113164711411017251 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include FILE *g_logfp = NULL; int g_log_modules_mask = 0xffff; int g_log_level = 0; void log_init( void ) { char *tmp = getenv( "UNICAP_EUVCCAM_LOG_PATH" ); if( tmp ) g_logfp = fopen( tmp, "w" ); tmp = getenv( "UNICAP_EUVCCAM_LOG_LEVEL" ); if( tmp ) g_log_level = atoi( tmp ); tmp = getenv( "UNICAP_EUVCCAM_LOG_MODULES_MASK" ); if( tmp ) g_log_modules_mask = atoi( tmp ); } void log_close( void ) { if( g_logfp ) fclose( g_logfp ); g_logfp = NULL; } void log_message( int module, int log_level, const char *format, ... ) { if( ( module & g_log_modules_mask ) && ( log_level > g_log_level ) ){ char message[ 128 ]; va_list ap; va_start( ap, format ); vsnprintf( message, sizeof( message ), format, ap ); va_end( ap ); if( g_logfp ){ fwrite( message, strlen( message ), 1, g_logfp ); fflush( g_logfp ); }else{ printf( "%s", message ); } } } libunicap/cpi/euvccam/euvccam_capture.h0000644000175000017500000000201113164711411020764 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __EUVCCAM_CAPTURE_H__ #define __EUVCCAM_CAPTURE_H__ #include "euvccam_cpi.h" unicap_status_t euvccam_capture_start_capture( euvccam_handle_t handle ); unicap_status_t euvccam_capture_stop_capture( euvccam_handle_t handle ); #endif//__EUVCCAM_CAPTURE_H__ libunicap/cpi/euvccam/euvccam_capture.c0000644000175000017500000002714513164711411020776 0ustar zmoelnigzmoelnig/* unicap euvccam plugin Copyright (C) 2009 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "euvccam_cpi.h" #include "euvccam_devspec.h" #include "euvccam_colorproc.h" #include "queue.h" #define MAX_READ_WRITE (16 * 1024) #define NUM_URBS 32 #define NUM_SYSTEM_BUFFERS 8 static void sighandler(int sig ) { return; } struct buffer_done_context { sem_t sema; unicap_data_buffer_t *buffer; unicap_data_buffer_t *conv_buffer; euvccam_convert_func_t conv_func; euvccam_handle_t euvccam_handle; volatile int quit; unicap_handle_t unicap_handle; unicap_event_callback_t event_callback; }; struct timeout_thread_context { volatile euvccam_handle_t handle; struct timeval timeout; volatile int quit; }; static void *timeout_thread( struct timeout_thread_context *context ) { while (!context->quit){ struct timeval tv; gettimeofday (&tv, NULL); if ((context->timeout.tv_sec + 2) < tv.tv_sec){ TRACE ("capture timeout\n"); pthread_kill (context->handle->capture_thread, SIGUSR1); } sleep( 1 ); } return NULL; } static void *buffer_done_thread( struct buffer_done_context *context ) { while( !context->quit ){ struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 1; if( sem_timedwait( &context->sema, &ts) != 0 ) continue; if( context->quit ) break; if( context->event_callback ){ if( context->conv_buffer && context->conv_func ){ if( context->euvccam_handle->debayer_data.wb_auto_mode != WB_MODE_MANUAL ){ euvccam_colorproc_auto_wb( context->euvccam_handle, context->buffer ); if( context->euvccam_handle->debayer_data.wb_auto_mode == WB_MODE_ONE_PUSH ) context->euvccam_handle->debayer_data.wb_auto_mode = WB_MODE_MANUAL; } context->conv_func( context->euvccam_handle, context->conv_buffer, context->buffer ); context->event_callback( context->unicap_handle, UNICAP_EVENT_NEW_FRAME, context->conv_buffer ); }else{ context->event_callback( context->unicap_handle, UNICAP_EVENT_NEW_FRAME, context->buffer ); } } } return NULL; } static void buffer_done( euvccam_handle_t handle, struct buffer_done_context *context ) { gettimeofday( &context->buffer->fill_time, NULL ); sem_post( &context->sema ); } static int __inline__ submit_urb( int fd, struct usbdevfs_urb *urb ) { return ioctl( fd, USBDEVFS_SUBMITURB, urb ); } static int __inline__ reap_urb( int fd, struct usbdevfs_urb **urb ) { return ioctl( fd, USBDEVFS_REAPURB, urb ); } static void *capture_thread( euvccam_handle_t handle ) { unsigned char *usb_buffer[NUM_URBS]; int i; int bytes_done = 0; int current_buffer = 0; int wait_transfer_done = 0; int usb_buffer_size = 0; pthread_t buffer_done_thread_id = 0; struct buffer_done_context context; unicap_data_buffer_t system_buffers[ NUM_SYSTEM_BUFFERS ]; struct usbdevfs_urb *urbs[NUM_URBS]; pthread_t capture_timeout_thread_id = 0; struct timeout_thread_context timeout_context; if( handle->current_format->usb_buffer_size == 0 ){ TRACE( "Invalid video format!\n" ); abort(); return NULL; } usb_buffer_size = handle->current_format->format.size.width * handle->current_format->format.size.height; signal( SIGUSR1, sighandler ); sem_init( &context.sema, 0, 0 ); context.buffer = NULL; context.conv_buffer = NULL; context.conv_func = NULL; context.quit = 0; context.euvccam_handle = handle; context.unicap_handle = handle->unicap_handle; context.event_callback = handle->event_callback; if( handle->current_format->convert_func ){ context.conv_buffer = calloc( 1, sizeof( unicap_data_buffer_t ) ); unicap_copy_format( &context.conv_buffer->format, &handle->current_format->format ); context.conv_buffer->buffer_size = context.conv_buffer->format.buffer_size; context.conv_buffer->data = malloc( context.conv_buffer->format.buffer_size ); context.conv_buffer->type = UNICAP_FLAGS_BUFFER_TYPE_SYSTEM; context.conv_buffer->flags = 0; context.conv_buffer->frame_number = 0; context.conv_func = handle->current_format->convert_func; } if( pthread_create( &buffer_done_thread_id, NULL, (void*(*)(void*))buffer_done_thread, &context ) != 0 ){ sem_destroy( &context.sema ); return NULL; } gettimeofday( &timeout_context.timeout, NULL ); timeout_context.handle = handle; timeout_context.quit = 0; if( pthread_create ( &capture_timeout_thread_id, NULL, (void*(*)(void*))timeout_thread, &timeout_context) != 0 ){ return NULL; } for( i = 0; i < NUM_URBS; i++ ){ struct usbdevfs_urb *urb; int ret; usb_buffer[i] = (unsigned char *)malloc( MAX_READ_WRITE ); if( !usb_buffer[i] ){ int j; for( j = 0; j < i; j++ ){ free( usb_buffer[j] ); } return NULL; } urb = malloc( sizeof( struct usbdevfs_urb ) ); if( !urb ) return NULL; // TODO: free URBs and buffers on failure memset( urb, 0x0, sizeof( struct usbdevfs_urb ) ); urb->type = USBDEVFS_URB_TYPE_BULK; urb->endpoint = handle->streaming_endpoint; urb->buffer = usb_buffer[i]; urb->buffer_length = MAX_READ_WRITE; ret = submit_urb( handle->dev.fd, urb ); if( ret < 0 ){ TRACE( "Failed to submit urb!\n" ); perror( "ioctl" ); return NULL; } urbs[i] = urb; } for( i = 0; i < NUM_SYSTEM_BUFFERS; i++ ){ unicap_copy_format( &system_buffers[i].format, &handle->current_format->format ); system_buffers[i].buffer_size = /* handle->current_format-> */usb_buffer_size; system_buffers[i].data = malloc( system_buffers[i].buffer_size ); system_buffers[i].type = UNICAP_FLAGS_BUFFER_TYPE_SYSTEM; system_buffers[i].flags = 0; system_buffers[i].frame_number = 0; memset( &system_buffers[i].fill_time, 0x0, sizeof( struct timeval ) ); memset( &system_buffers[i].duration, 0x0, sizeof( struct timeval ) ); memset( &system_buffers[i].capture_start_time, 0x0, sizeof( struct timeval ) ); } while( !handle->capture_thread_quit && !handle->removed){ struct usbdevfs_urb *urb; int ret; int corrupt_frame = 0; ret = reap_urb(handle->dev.fd, &urb); gettimeofday (&timeout_context.timeout, NULL); if( ret < 0 ){ switch( errno ){ case ENODEV: TRACE( "NODEV\n" ); if( !handle->removed){ handle->removed = 1; } break; default: case EAGAIN: /* perror( "reap: " ); */ usleep(1000); continue; break; //fail break; } // on error - break out of the loop break; } else { int transfer_done = 0; if( urb->actual_length == 0 ){ submit_urb( handle->dev.fd, urb ); usleep(1000); continue; } if( urb->actual_length < urb->buffer_length ){ transfer_done = 1; wait_transfer_done = 0; }else if( wait_transfer_done ){ submit_urb( handle->dev.fd, urb ); continue; } if( bytes_done == 0 ){ // first packet in stream: skip header memcpy( system_buffers[ current_buffer ].data, urb->buffer + 2, urb->actual_length - 2 ); bytes_done += urb->actual_length - 2; system_buffers[ current_buffer ].buffer_size = bytes_done; }else{ if( ( bytes_done + urb->actual_length ) <= /* handle->current_format-> */usb_buffer_size ){ memcpy( system_buffers[ current_buffer ].data + bytes_done, urb->buffer, urb->actual_length ); bytes_done += urb->actual_length; system_buffers[ current_buffer ].buffer_size = bytes_done; }else{ corrupt_frame = 1; transfer_done = 1; if( !transfer_done ) wait_transfer_done = 1; TRACE( "corrupt_frame: bytes = %d / %d \n", bytes_done + urb->actual_length, /* handle->current_format-> */usb_buffer_size ); bytes_done = 0; } } if( transfer_done ){ if( !corrupt_frame && ( bytes_done == /* handle->current_format-> */usb_buffer_size ) ){ context.buffer = &system_buffers[ current_buffer ]; buffer_done( handle, &context ); current_buffer = ( current_buffer + 1 ) % NUM_SYSTEM_BUFFERS; }else{ context.buffer = &system_buffers[ current_buffer ]; buffer_done( handle, &context ); current_buffer = ( current_buffer + 1 ) % NUM_SYSTEM_BUFFERS; TRACE( "corrupt_frame: bytes = %d / %d \n", bytes_done, /* handle->current_format-> */usb_buffer_size ); } bytes_done = 0; system_buffers[ current_buffer ].buffer_size = 0; } submit_urb( handle->dev.fd, urb ); } } TRACE( "Capture thread exit\n" ); context.quit = 1; timeout_context.quit = 1; sem_post( &context.sema ); pthread_join( buffer_done_thread_id, NULL ); sem_destroy( &context.sema ); pthread_join( capture_timeout_thread_id, NULL ); if( context.conv_buffer ){ free( context.conv_buffer->data ); free( context.conv_buffer ); context.conv_buffer = NULL; } // Discard all URBs for( i = 0; i < NUM_URBS; i++ ){ struct usbdevfs_urb *urb = urbs[i]; int ret; ret = ioctl( handle->dev.fd, USBDEVFS_DISCARDURB, urb ); } // Reap all URBs and free buffers for( i = 0; i < NUM_URBS; i++ ){ struct usbdevfs_urb *urb; if( reap_urb( handle->dev.fd, &urb ) == 0 ){ free( urb->buffer ); free( urb ); } } for( i = 0; i < NUM_SYSTEM_BUFFERS; i++ ){ free( system_buffers[i].data ); } if( handle->removed && handle->event_callback ){ handle->event_callback( handle->unicap_handle, UNICAP_EVENT_DEVICE_REMOVED ); } return NULL; } unicap_status_t euvccam_capture_start_capture( euvccam_handle_t handle ) { struct sched_param param; if( handle->capture_running ) return STATUS_SUCCESS; handle->capture_thread_quit = 0; handle->streaming_endpoint = 0x82; if( pthread_create( &handle->capture_thread, NULL, (void*(*)(void*))capture_thread, handle ) != 0 ) return STATUS_FAILURE; param.sched_priority = 5; if( pthread_setschedparam( handle->capture_thread, SCHED_FIFO, ¶m ) == 0 ){ TRACE( "Successfully moved to RT scheduler\n" ); }else{ //perror( "pthread_setschedparam: " ); } handle->capture_running = 1; return STATUS_SUCCESS; } unicap_status_t euvccam_capture_stop_capture( euvccam_handle_t handle ) { if( handle->capture_running ){ TRACE( "Stop capture\n" ); /* // send signal to interrupt blocking ioctls */ pthread_kill( handle->capture_thread, SIGUSR1 ); handle->capture_thread_quit = 1; pthread_join( handle->capture_thread, NULL ); } handle->capture_running = 0; return STATUS_SUCCESS; } libunicap/cpi/dcam/0000755000175000017500000000000013164711411014734 5ustar zmoelnigzmoelniglibunicap/cpi/dcam/dcam_capture.c0000644000175000017500000003424213164711411017534 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "video1394.h" #include "dcam.h" #include "dcam_capture.h" #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" static void new_frame_event( dcam_handle_t dcamhandle, unicap_data_buffer_t *buffer ) { if( dcamhandle->event_callback ) { dcamhandle->event_callback( dcamhandle->unicap_handle, UNICAP_EVENT_NEW_FRAME, buffer ); } } static void drop_frame_event( dcam_handle_t dcamhandle ) { if( dcamhandle->event_callback ) { dcamhandle->event_callback( dcamhandle->unicap_handle, UNICAP_EVENT_NEW_FRAME ); } } static void cleanup_handler( void *arg ) { TRACE( "cleanup_handler\n" ); } /* loop in the background while capturing to call the iso handle regularly */ void *dcam_capture_thread( void *data ) { dcam_handle_t dcamhandle = (dcam_handle_t)data; pthread_cleanup_push( cleanup_handler, data ); while( dcamhandle->capture_running ) { raw1394_loop_iterate( dcamhandle->raw1394handle ); } pthread_cleanup_pop( 0 ); return 0; } /* handler for raw1394 isoch reception sequence: - get buffer from input queue - start on sy == 1 to fill buffer - fill buffer until dcamhandle->buffer_size is reached - put buffer into output queue */ enum raw1394_iso_disposition dcam_iso_handler( raw1394handle_t raw1394handle, unsigned char * data, unsigned int len, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped ) { dcam_handle_t dcamhandle = raw1394_get_userdata( raw1394handle ); if( !len ) { return 0; } /* TRACE( "len: %d, sy: %d, cycle: %d, dropped: %d,current_offset: %d, buffer_size: %d\n", */ /* len, */ /* sy, */ /* cycle, */ /* dropped, */ /* dcamhandle->current_buffer_offset, */ /* dcamhandle->buffer_size); */ if( dcamhandle->wait_for_sy ) { if( !sy ) { return 0; } dcamhandle->current_buffer_offset = 0; dcamhandle->current_buffer = ucutil_get_front_queue( &dcamhandle->input_queue ); if( !dcamhandle->current_buffer ) { return 0; } dcamhandle->wait_for_sy = 0; /* gettimeofday( &dcamhandle->current_buffer->fill_start_time, NULL ); */ } if( (dcamhandle->current_buffer_offset + len) > dcamhandle->buffer_size ) { TRACE( "dcam.cpi: (isoch handler) got more data than allowed\n" ); return 0; } memcpy( dcamhandle->current_buffer->data + dcamhandle->current_buffer_offset, data, len ); dcamhandle->current_buffer_offset += len; if( dcamhandle->current_buffer_offset == dcamhandle->buffer_size ) { /* gettimeofday( &dcamhandle->current_buffer->fill_end_time, NULL ); */ ucutil_insert_back_queue( &dcamhandle->output_queue, dcamhandle->current_buffer ); /* new_frame_event( dcamhandle, dcamhandle->current_buffer ); */ dcamhandle->current_buffer = 0; dcamhandle->wait_for_sy = 1; } return 0; } /* setup video1394 module for dma capture - opens /dev/video1394/%port% */ unicap_status_t _dcam_dma_setup( dcam_handle_t dcamhandle ) { char dev_file[512]; struct video1394_wait vwait; struct video1394_mmap vmmap; int i; sprintf( dev_file, "/dev/video1394/%d", dcamhandle->port ); dcamhandle->dma_fd = open( dev_file, O_RDONLY ); if( dcamhandle->dma_fd < 0 ) { struct stat statbuf; TRACE( "failed to open video1394 device %s\n", dev_file ); sprintf( dev_file, "/dev/video1394-%d", dcamhandle->port ); dcamhandle->dma_fd = open( dev_file, O_RDONLY ); if( dcamhandle->dma_fd < 0 ) { sprintf( dev_file, "/dev/video1394" ); if( !stat (dev_file, &statbuf) && !S_ISDIR(statbuf.st_mode) ) dcamhandle->dma_fd = open( dev_file, O_RDONLY ); if( dcamhandle->dma_fd < 0 ) { TRACE( "failed to open video1394 device %s\n", dev_file ); return STATUS_FAILURE; } } } dcamhandle->current_dma_capture_buffer = -1; TRACE( "dma setup buffer size: %d\n", dcamhandle->buffer_size ); vmmap.sync_tag = 1; vmmap.nb_buffers = DCAM_NUM_DMA_BUFFERS; vmmap.flags = VIDEO1394_SYNC_FRAMES; vmmap.buf_size = dcamhandle->buffer_size; vmmap.channel = dcamhandle->channel_allocated; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_CHANNEL, &vmmap ) < 0 ) { TRACE( "VIDEO1394_LISTEN_CHANNEL ioctl failed\n" ); TRACE( "error: %s\n", strerror( errno ) ); TRACE( "buffer_size: %d, channel: %d\n", vmmap.buf_size, vmmap.channel ); return STATUS_FAILURE; } dcamhandle->dma_vmmap_frame_size = vmmap.buf_size; dcamhandle->dma_buffer_size = DCAM_NUM_DMA_BUFFERS * dcamhandle->dma_vmmap_frame_size; dcamhandle->dma_buffer = mmap( 0, dcamhandle->dma_buffer_size, PROT_READ, MAP_SHARED, dcamhandle->dma_fd, 0 ); if( dcamhandle->dma_buffer == (unsigned char *)(-1) ) { TRACE( "mmap failed\n" ); ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_UNLISTEN_CHANNEL, &vmmap.channel ); return STATUS_FAILURE; } for( i = 0; i < DCAM_NUM_DMA_BUFFERS; i++ ) { vwait.channel = dcamhandle->channel_allocated; vwait.buffer = i; TRACE( "q: %d\n", vwait.buffer ); if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait ) < 0 ) { TRACE( "VIDEO1394_LISTEN_QUEUE_BUFFER ioctl failed\n" ); return STATUS_FAILURE; } } return STATUS_SUCCESS; } /* free resources acquired by dma_init */ unicap_status_t _dcam_dma_free( dcam_handle_t dcamhandle ) { if( dcamhandle->dma_buffer ) { munmap( dcamhandle->dma_buffer, dcamhandle->dma_buffer_size ); } close( dcamhandle->dma_fd ); return STATUS_SUCCESS; } /* dma unlisten */ unicap_status_t _dcam_dma_unlisten( dcam_handle_t dcamhandle ) { int channel = dcamhandle->channel_allocated; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_UNLISTEN_CHANNEL, &channel ) < 0 ) { return STATUS_FAILURE; } return STATUS_SUCCESS; } static void sighandler(int sig ) { return; } void *dcam_dma_capture_thread( void *arg ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) arg; struct video1394_wait vwait; unicap_queue_t *entry; int i = 0; int ready_buffer; signal( SIGUSR1, sighandler ); while( dcamhandle->dma_capture_thread_quit == 0 ) { vwait.channel = dcamhandle->channel_allocated; i = vwait.buffer = ( dcamhandle->current_dma_capture_buffer + 1 ) % DCAM_NUM_DMA_BUFFERS; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_WAIT_BUFFER, &vwait ) != 0 ) { TRACE( "VIDEO1394_LISTEN_WAIT_BUFFER ioctl failed\n" ); TRACE( "channel: %d, buffer: %d\n", vwait.channel, vwait.buffer ); TRACE( "error: %s\n", strerror( errno ) ); // increase the buffer counter to wait for next buffer on the next try dcamhandle->current_dma_capture_buffer = ( dcamhandle->current_dma_capture_buffer + 1 ) % DCAM_NUM_DMA_BUFFERS; usleep( 25000 ); continue; } ready_buffer = ( vwait.buffer + i ) % DCAM_NUM_DMA_BUFFERS; entry = ucutil_get_front_queue( &dcamhandle->input_queue ); if( entry ) { unicap_data_buffer_t *data_buffer; data_buffer = entry->data; memcpy( &data_buffer->fill_time, &vwait.filltime, sizeof( struct timeval ) ); if( data_buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) { data_buffer->data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; } else { memcpy( data_buffer->data, dcamhandle->dma_buffer + i * dcamhandle->dma_vmmap_frame_size, dcamhandle->buffer_size ); } data_buffer->buffer_size = dcamhandle->buffer_size; ucutil_insert_back_queue( &dcamhandle->output_queue, entry ); data_buffer = 0; } { unicap_data_buffer_t tmpbuffer; tmpbuffer.data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; tmpbuffer.buffer_size = dcamhandle->buffer_size; unicap_copy_format( &tmpbuffer.format, &dcamhandle->v_format_array[dcamhandle->current_format_index] ); memcpy( &tmpbuffer.fill_time, &vwait.filltime, sizeof( struct timeval ) ); new_frame_event( dcamhandle, &tmpbuffer ); } for( ; i != ready_buffer; i = ( ( i + 1 ) % DCAM_NUM_DMA_BUFFERS ) ) { entry = ucutil_get_front_queue( &dcamhandle->input_queue ); if( entry ) { unicap_data_buffer_t *data_buffer; data_buffer = entry->data; memcpy( &data_buffer->fill_time, &vwait.filltime, sizeof( struct timeval ) ); if( data_buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) { data_buffer->data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; } else { memcpy( data_buffer->data, dcamhandle->dma_buffer + i * dcamhandle->dma_vmmap_frame_size, dcamhandle->buffer_size ); } data_buffer->buffer_size = dcamhandle->buffer_size; ucutil_insert_back_queue( &dcamhandle->output_queue, entry ); data_buffer = 0; } { unicap_data_buffer_t tmpbuffer; tmpbuffer.data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; tmpbuffer.buffer_size = dcamhandle->buffer_size; unicap_copy_format( &tmpbuffer.format, &dcamhandle->v_format_array[dcamhandle->current_format_index] ); new_frame_event( dcamhandle, &tmpbuffer ); } vwait.buffer = i; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait ) < 0 ) { TRACE( "VIDEO1394_LISTEN_QUEUE_BUFFER ioctl failed\n" ); continue; } } vwait.buffer = ready_buffer; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait ) < 0 ) { TRACE( "VIDEO1394_LISTEN_QUEUE_BUFFER ioctl failed\n" ); continue; } dcamhandle->current_dma_capture_buffer = ready_buffer; } return NULL; } unicap_status_t dcam_dma_wait_buffer( dcam_handle_t dcamhandle ) { struct video1394_wait vwait; unicap_queue_t *entry; int i = 0; int ready_buffer; vwait.channel = dcamhandle->channel_allocated; i = vwait.buffer = ( dcamhandle->current_dma_capture_buffer + 1 ) % DCAM_NUM_DMA_BUFFERS; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_WAIT_BUFFER, &vwait ) != 0 ) { TRACE( "VIDEO1394_LISTEN_WAIT_BUFFER ioctl failed\n" ); TRACE( "channel: %d, buffer: %d\n", vwait.channel, vwait.buffer ); TRACE( "error: %s\n", strerror( errno ) ); // increase the buffer counter to wait for next buffer on the next try dcamhandle->current_dma_capture_buffer = ( dcamhandle->current_dma_capture_buffer + 1 ) % DCAM_NUM_DMA_BUFFERS; return STATUS_FAILURE; } ready_buffer = ( vwait.buffer + i ) % DCAM_NUM_DMA_BUFFERS; entry = ucutil_get_front_queue( &dcamhandle->input_queue ); if( entry ) { unicap_data_buffer_t *data_buffer; data_buffer = entry->data; memcpy( &data_buffer->fill_time, &vwait.filltime, sizeof( struct timeval ) ); if( data_buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) { data_buffer->data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; } else { memcpy( data_buffer->data, dcamhandle->dma_buffer + i * dcamhandle->dma_vmmap_frame_size, dcamhandle->buffer_size ); } data_buffer->buffer_size = dcamhandle->buffer_size; ucutil_insert_back_queue( &dcamhandle->output_queue, entry ); data_buffer = 0; } { unicap_data_buffer_t tmpbuffer; tmpbuffer.data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; tmpbuffer.buffer_size = dcamhandle->buffer_size; unicap_copy_format( &tmpbuffer.format, &dcamhandle->v_format_array[dcamhandle->current_format_index] ); memcpy( &tmpbuffer.fill_time, &vwait.filltime, sizeof( struct timeval ) ); new_frame_event( dcamhandle, &tmpbuffer ); } for( ; i != ready_buffer; i = ( ( i + 1 ) % DCAM_NUM_DMA_BUFFERS ) ) { entry = ucutil_get_front_queue( &dcamhandle->input_queue ); if( entry ) { unicap_data_buffer_t *data_buffer; data_buffer = entry->data; memcpy( &data_buffer->fill_time, &vwait.filltime, sizeof( struct timeval ) ); if( data_buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) { data_buffer->data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; } else { memcpy( data_buffer->data, dcamhandle->dma_buffer + i * dcamhandle->dma_vmmap_frame_size, dcamhandle->buffer_size ); } data_buffer->buffer_size = dcamhandle->buffer_size; ucutil_insert_back_queue( &dcamhandle->output_queue, entry ); data_buffer = 0; } { unicap_data_buffer_t tmpbuffer; tmpbuffer.data = dcamhandle->dma_buffer + i * dcamhandle->buffer_size; tmpbuffer.buffer_size = dcamhandle->buffer_size; unicap_copy_format( &tmpbuffer.format, &dcamhandle->v_format_array[dcamhandle->current_format_index] ); new_frame_event( dcamhandle, &tmpbuffer ); } vwait.buffer = i; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait ) < 0 ) { TRACE( "VIDEO1394_LISTEN_QUEUE_BUFFER ioctl failed\n" ); return STATUS_FAILURE; } } vwait.buffer = ready_buffer; if( ioctl( dcamhandle->dma_fd, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, &vwait ) < 0 ) { TRACE( "VIDEO1394_LISTEN_QUEUE_BUFFER ioctl failed\n" ); return STATUS_FAILURE; } dcamhandle->current_dma_capture_buffer = ready_buffer; return STATUS_SUCCESS; } libunicap/cpi/dcam/dcam_offsets.h0000644000175000017500000000200213164711411017534 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_OFFSETS_H__ #define __DCAM_OFFSETS_H__ #define O_FORMAT_INQ 0x100 #define O_MODE_INQ_BASE 0x180 #define O_CUR_MODE 0x604 #define O_CUR_FORMAT 0x608 #define O_ISO_CTRL 0x614 #endif//__DCAM_OFFSETS_H__ libunicap/cpi/dcam/dcam_busreset.c0000644000175000017500000001014513164711411017721 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "dcam.h" #include "dcam_functions.h" #include "dcam_busreset.h" #include "1394util.h" #include #include #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" extern struct _dcam_isoch_mode dcam_isoch_table[]; static void dcam_device_removed_event( dcam_handle_t dcamhandle ) { if( dcamhandle->event_callback ) { dcamhandle->event_callback( dcamhandle->unicap_handle, UNICAP_EVENT_DEVICE_REMOVED ); } } /* bus reset handler checks if device is still on the bus. if it is removed -> set device_present to 0 . bandwidth and channel are remotely freed on bus reset if device still present -> reallocate bw and channel -> channel is not guarranted to be the same after reallocation -> set new channel to camera if changed */ int dcam_busreset_handler( raw1394handle_t raw1394handle, unsigned int generation ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) raw1394_get_userdata( raw1394handle ); int port; int channel; raw1394_update_generation( raw1394handle, generation ); // check if the device is still there or if it has changed if( _dcam_find_device( &dcamhandle->unicap_device, &port, &dcamhandle->node, &dcamhandle->directory ) != STATUS_SUCCESS ) { dcamhandle->device_present = 0; dcam_device_removed_event( dcamhandle ); return 0; } // what happens if a PC-Card is removed ? does this change the port??? if( port != dcamhandle->port ) { if( raw1394_set_port( raw1394handle, port ) < 0 ) { dcamhandle->device_present = 0; dcam_device_removed_event( dcamhandle ); return 0; } dcamhandle->port = port; } // reallocate bandwidth // ( reallocation should always succeed ) if( dcamhandle->allocate_bandwidth ) { if( !SUCCESS(_1394util_allocate_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ) ) ) { TRACE( "dcam.cpi: failed to reallocate bandwidth\n" ); dcam_capture_stop( dcamhandle ); return 0; } } // channel is freed on busreset // -> reallocate channel // check if newly allocated channel matches previous channel // -> conditionaly set new channel on the camera if( !SUCCESS(_1394util_allocate_channel(dcamhandle->raw1394handle, dcamhandle->channel_allocated ) ) ) { if( ( channel = _1394util_find_free_channel( dcamhandle->raw1394handle ) ) < 0 ) { TRACE( "dcam.cpi: failed to allocate channel\n"); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); dcam_capture_stop( dcamhandle ); return 0; } if( channel != dcamhandle->channel_allocated ) { quadlet_t quad = 0; if( dcam_isoch_table[dcamhandle->current_iso_index].min_speed <= S400 ) { quad = ( channel << 28 ) | ( S400 << 24 ); } else { quad = ( channel << 28 ) | ( dcam_isoch_table[dcamhandle->current_iso_index].min_speed << 24 ); } if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x60c, quad ) < 0 ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); return 0; } } } return 0; } libunicap/cpi/dcam/dcam_juju_capture.c0000644000175000017500000002566613164711411020603 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dcam.h" #include "dcam_juju.h" #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" #define __HIDDEN__ __attribute__((visibility("hidden"))) #define ptr_to_u64(p) ((__u64)(unsigned long)(p)) #define u64_to_ptr(p) ((void *)(unsigned long)(p)) extern struct _dcam_isoch_mode dcam_isoch_table[]; static void new_frame_event( dcam_handle_t dcamhandle, unicap_data_buffer_t *buffer ) { if( dcamhandle->event_callback ) { dcamhandle->event_callback( dcamhandle->unicap_handle, UNICAP_EVENT_NEW_FRAME, buffer ); } } static void drop_frame_event( dcam_handle_t dcamhandle ) { if( dcamhandle->event_callback ) { dcamhandle->event_callback( dcamhandle->unicap_handle, UNICAP_EVENT_NEW_FRAME ); } } static void cleanup_handler( void *arg ) { TRACE( "cleanup_handler\n" ); } int dcam_juju_probe (dcam_handle_t dcamhandle) { int fd; char filename[PATH_MAX]; int ret = 0; struct fw_cdev_get_info info; sprintf (filename, "/dev/fw%d", dcamhandle->port); fd = open (filename, O_RDWR); if (fd < 0){ TRACE ("Probe for JUJU: device file inaccessible\n"); return 0; } info.version = FW_CDEV_VERSION; info.rom = 0; info.rom_length = 0; info.bus_reset = 0; if (ioctl (fd, FW_CDEV_IOC_GET_INFO, &info) < 0){ TRACE ("Probe for JUJU: failed to retrieve info\n"); close (fd); return 0; } if (info.version < 2){ TRACE ("Probe for JUJU: ABI version 1 unsupported\n"); return 0; } close (fd); return 1; } unicap_status_t __HIDDEN__ dcam_juju_setup (dcam_handle_t dcamhandle) { struct fw_cdev_create_iso_context create; char filename[PATH_MAX]; sprintf (filename, "/dev/fw%d", dcamhandle->port); dcamhandle->dma_fd = open (filename, O_RDWR); if (dcamhandle->dma_fd < 0){ TRACE ("JUJU setup: device file inaccessible\n"); return STATUS_FAILURE; } create.type = FW_CDEV_ISO_CONTEXT_RECEIVE; create.header_size = 8; create.channel = dcamhandle->channel_allocated; create.speed = S400; if (ioctl (dcamhandle->dma_fd, FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create) < 0){ TRACE ("Failed to create iso context\n"); return STATUS_FAILURE; } dcamhandle->juju_iso_handle = create.handle; dcamhandle->dma_buffer_size = DCAM_NUM_DMA_BUFFERS * dcamhandle->buffer_size; dcamhandle->dma_buffer = mmap (NULL, dcamhandle->dma_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, dcamhandle->dma_fd, 0); if (dcamhandle->dma_buffer == MAP_FAILED){ TRACE ("Failed to map dma buffer\n"); return STATUS_FAILURE; } return STATUS_SUCCESS; } unicap_status_t dcam_juju_prepare_iso (dcam_handle_t dcamhandle) { int i; size_t packet_size = dcam_isoch_table[dcamhandle->current_iso_index] .bytes_per_packet; size_t frame_size = dcam_isoch_table[dcamhandle->current_iso_index] .bytes_per_frame; int iso_packets_per_frame = frame_size / packet_size; int cdev_iso_packet_count = 8; int cdev_packets_per_frame = ((iso_packets_per_frame + cdev_iso_packet_count - 1 ) / cdev_iso_packet_count); size_t size = cdev_packets_per_frame * sizeof (struct fw_cdev_iso_packet); for (i=0; i < DCAM_NUM_DMA_BUFFERS; i++){ int j; int packets_left = iso_packets_per_frame; int packet_count = cdev_iso_packet_count; struct fw_cdev_iso_packet *packets; dcamhandle->juju_buffers[i].packets = calloc (size, 1); dcamhandle->juju_buffers[i].size = size; if (!dcamhandle->juju_buffers[i].packets){ TRACE ("Failed to allocate packets"); for (j = 0; j < i-1; j++) free (dcamhandle->juju_buffers[i].packets); return STATUS_FAILURE; } packets = dcamhandle->juju_buffers[i] .packets; for (j = 0; j < cdev_packets_per_frame; j++){ if (packets_left < packet_count) packet_count = packets_left; packets[j].control = FW_CDEV_ISO_HEADER_LENGTH (8 * packet_count) | FW_CDEV_ISO_PAYLOAD_LENGTH (packet_size * packet_count); packets_left -= packet_count; } packets[0].control |= FW_CDEV_ISO_SKIP; packets[cdev_packets_per_frame - 1].control |= FW_CDEV_ISO_INTERRUPT; } for (i=0; i < DCAM_NUM_DMA_BUFFERS; i++) dcam_juju_queue_buffer (dcamhandle, i); return STATUS_SUCCESS; } unicap_status_t dcam_juju_start_iso (dcam_handle_t dcamhandle) { struct fw_cdev_start_iso start_iso; int ret; start_iso.cycle = -1; start_iso.tags = FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS; start_iso.sync = 1; start_iso.handle = dcamhandle->juju_iso_handle; ret = ioctl (dcamhandle->dma_fd, FW_CDEV_IOC_START_ISO, &start_iso); if (ret < 0 ){ TRACE ("Failed to start iso\n"); return STATUS_FAILURE; } return STATUS_SUCCESS; } unicap_status_t dcam_juju_shutdown (dcam_handle_t dcamhandle) { unicap_status_t status = STATUS_SUCCESS; struct fw_cdev_stop_iso stop_iso; if (dcamhandle->dma_fd > 0){ int i; if (ioctl(dcamhandle->dma_fd, FW_CDEV_IOC_STOP_ISO, &stop_iso) < 0){ TRACE ("Failed to stop iso\n"); status = STATUS_FAILURE; } munmap(dcamhandle->dma_buffer, dcamhandle->dma_buffer_size); for (i=0; i < DCAM_NUM_DMA_BUFFERS; i++){ free (dcamhandle->juju_buffers[i].packets); } close (dcamhandle->dma_fd); dcamhandle->dma_fd = -1; } return status; } unicap_status_t dcam_juju_queue_buffer (dcam_handle_t dcamhandle, int index) { struct fw_cdev_queue_iso queue; struct dcam_juju_buffer *buffer = dcamhandle->juju_buffers + index; queue.size = buffer->size; queue.data = ptr_to_u64 (dcamhandle->dma_buffer + (index * dcamhandle->buffer_size)); queue.packets = ptr_to_u64 (buffer->packets); queue.handle = dcamhandle->juju_iso_handle; if (ioctl (dcamhandle->dma_fd, FW_CDEV_IOC_QUEUE_ISO, &queue) < 0){ TRACE ("Failed to queue iso buffer\n"); return STATUS_FAILURE; } return STATUS_SUCCESS; } unicap_status_t dcam_juju_dequeue_buffer (dcam_handle_t dcamhandle, int *index, uint32_t *cycle_time, int *packet_discont) { struct pollfd fds[1]; size_t packet_size = dcam_isoch_table[dcamhandle->current_iso_index] .bytes_per_packet; size_t frame_size = dcam_isoch_table[dcamhandle->current_iso_index] .bytes_per_frame; int iso_packets_per_frame = frame_size / packet_size; struct { struct fw_cdev_event_iso_interrupt irq; uint32_t headers[iso_packets_per_frame*2 + 16]; } iso; fds[0].fd = dcamhandle->dma_fd; fds[0].events = POLLIN; while ( dcamhandle->dma_capture_thread_quit == 0 ){ int err, len; err = poll (fds, 1, -1); if (err <= 0){ if (errno == EINTR) continue; return STATUS_FAILURE; } len = read (dcamhandle->dma_fd, &iso, sizeof (iso)); if (len < 0){ TRACE ("Failed to read juju response\n"); return STATUS_FAILURE; } if (iso.irq.type == FW_CDEV_EVENT_ISO_INTERRUPT) break; } if (dcamhandle->dma_capture_thread_quit != 0){ return STATUS_FAILURE; } int i; uint8_t *bytes = (uint8_t *)(iso.headers+1); uint32_t cycle = (bytes[2] << 8) | bytes[3]; *packet_discont = 0; for (i = 1; i < iso_packets_per_frame; i++){ uint8_t *bytes = (uint8_t *)(iso.headers+(i*2+1)); uint32_t new_cycle = (bytes[2] << 8) | bytes[3]; // The Imaging Source cameras may have a 1 packet "gap" if ((abs(new_cycle-(cycle+1))%65535) > 2){ *packet_discont = 1; break; } cycle = new_cycle; } *index = dcamhandle->current_dma_capture_buffer; dcamhandle->current_dma_capture_buffer = (dcamhandle->current_dma_capture_buffer + 1) % DCAM_NUM_DMA_BUFFERS; return STATUS_SUCCESS; } static void sighandler(int sig ) { return; } static uint32_t calc_usec (uint32_t cycles) { uint32_t sec = (cycles & 0xe000000) >> 13; uint32_t cyc = (cycles & 0x1fff000); uint32_t usec = sec * 1000000 + cycles * 125; return usec; } void *dcam_juju_capture_thread( void *arg ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) arg; unicap_queue_t *entry; int ready_buffer; signal( SIGUSR1, sighandler ); while( dcamhandle->dma_capture_thread_quit == 0 ) { int index; unicap_queue_t *entry; int packet_discont = 0; struct fw_cdev_get_cycle_timer tm; uint32_t cycle_time; struct timeval tv; if (!SUCCESS( dcam_juju_dequeue_buffer (dcamhandle, &index, &cycle_time, &packet_discont))){ TRACE ("Dequeue failed!\n"); continue; } if (packet_discont && dcamhandle->enable_frame_drop){ TRACE ("Drop buffer\n"); // packet discontinuity -> drop buffer if (!SUCCESS (dcam_juju_queue_buffer (dcamhandle, index))){ TRACE ("Failed to queue buffer\n"); } } /* if (ioctl (dcamhandle->dma_fd, */ /* FW_CDEV_IOC_GET_CYCLE_TIMER, */ /* &tm) == 0){ */ /* uint32_t usec; */ /* calc_usec (cycle_time); */ /* } */ gettimeofday (&tv, NULL); entry = ucutil_get_front_queue( &dcamhandle->input_queue ); if (entry){ unicap_data_buffer_t *data_buffer; data_buffer = entry->data; if( data_buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ){ data_buffer->data = dcamhandle->dma_buffer + index * dcamhandle->buffer_size; } else { memcpy( data_buffer->data, ( dcamhandle->dma_buffer + index * dcamhandle->buffer_size), dcamhandle->buffer_size ); } data_buffer->buffer_size = dcamhandle->buffer_size; memcpy (&data_buffer->fill_time, &tv, sizeof (struct timeval)); ucutil_insert_back_queue( &dcamhandle->output_queue, entry ); data_buffer = 0; } { unicap_data_buffer_t tmpbuffer; tmpbuffer.data = dcamhandle->dma_buffer + index * dcamhandle->buffer_size; tmpbuffer.buffer_size = dcamhandle->buffer_size; unicap_copy_format( &tmpbuffer.format, &dcamhandle-> v_format_array[dcamhandle-> current_format_index] ); memcpy (&tmpbuffer.fill_time, &tv, sizeof (struct timeval)); new_frame_event( dcamhandle, &tmpbuffer ); } if (!SUCCESS (dcam_juju_queue_buffer (dcamhandle, index))){ TRACE ("Failed to queue buffer\n"); } } return NULL; } libunicap/cpi/dcam/Makefile.am0000644000175000017500000000172513164711411016775 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in INCLUDES = -I../include -I../../include -I../../ -I../../common @LIBRAW1394_PACKAGE_CFLAGS@ if ENABLE_STATIC_CPI noinst_LTLIBRARIES = libdcam.la libdcam_la_LIBADD = @LIBRAW1394_PACKAGE_LIBS@ @PTHREAD_LIBS@ -L../../common -lucutils else libcpi_LTLIBRARIES = libdcam.la libdcam_la_LIBADD = @LIBRAW1394_PACKAGE_LIBS@ @PTHREAD_LIBS@ -L../../src/.libs/ -lunicap -L../../common -lucutils endif libcpidir = $(libdir)/unicap$(pkg_version)/cpi libdcam_la_CPPFLAGS = -D@LIBRAW1394_VERSION@ libdcam_la_CFLAGS = -fno-strict-aliasing -Wl,-z,defs libdcam_la_LDFLAGS = -module -avoid-version libdcam_la_SOURCES = \ 1394util.c \ dcam.c dcam.h \ dcam_busreset.c dcam_busreset.h \ dcam_capture.c dcam_capture.h \ dcam_juju_capture.c dcam_juju.h \ dcam_defs.h \ dcam_format_table.h \ dcam_functions.c dcam_functions.h \ dcam_isoch_table.h \ dcam_offsets.h \ dcam_property.c dcam_property.h dcam_property_table.h \ dcam_v_modes.c dcam_v_modes.h libunicap/cpi/dcam/dcam_defs.h0000644000175000017500000000367113164711411017021 0ustar zmoelnigzmoelnig#ifndef __DCAM_DEFS_H__ #define __DCAM_DEFS_H__ #define GETFLAG_MANUAL_INQ(x) ( ( x>>24 ) & 1 ) #define SETFLAG_MANUAL_INQ(x,y) ( x | ( (y&1)<<24 ) ) #define GETFLAG_AUTO_INQ(x) ( ( x>>25 ) & 1 ) #define SETFLAG_AUTO_INQ(x,y) ( x | ( (y&1)<<25 ) ) #define GETFLAG_ON_OFF_INQ(x) ( ( x>>26 ) & 1 ) #define SETFLAG_ON_OFF_INQ(x,y) ( x | ( (y&1)<<26 ) ) #define GETFLAG_READ_OUT_INQ(x) ( ( x>>27 ) & 1 ) #define SETFLAG_READ_OUT_INQ(x,y)( x | ( (y&1)<<27 ) ) #define GETFLAG_ONE_PUSH_INQ(x) ( ( x>>28 ) & 1 ) #define SETFLAG_ONE_PUSH_INQ(x,y)( x | ( (y&1)<<28 ) ) #define GETFLAG_ABS_CONTROL_INQ(x) ( ( x>>30 ) & 1 ) #define SETFLAG_ABS_CONTROL_INQ(x,y)( x | ( (y&1)<<30 ) ) #define GETFLAG_PRESENCE_INQ(x) ( ( x>>31 ) & 1 ) #define SETFLAG_PRESENCE_INQ(x,y)( x | ( (y&1)<<31 ) ) #define GETFLAG_AUTO(x) ( ( x>>24 ) & 1 ) #define SETFLAG_AUTO(x,y) ( ( x & ~(1<<24) ) | ( (y&1)<<24 ) ) #define GETFLAG_ON_OFF(x) ( ( x>>25 ) & 1 ) #define SETFLAG_ON_OFF(x,y) ( ( x & ~(1<<25) ) | ( (y&1)<<25 ) ) #define GETFLAG_ONE_PUSH(x) ( ( x>>26 ) & 1 ) #define SETFLAG_ONE_PUSH(x,y) ( ( x & ~(1<<26) ) | ( (y&1)<<26 ) ) #define GETFLAG_ABS_CONTROL(x) ( ( x>>30 ) & 1 ) #define SETFLAG_ABS_CONTROL(x,y) ( ( x & ~(1<<30) ) | ( (y&1)<<30 ) ) #define GETFLAG_PRESENCE(x) ( ( x>>31 ) & 1 ) #define SETFLAG_PRESENCE(x,y) ( ( x & ~(1<<31) ) | ( (y&1)<<31 ) ) #define GETVAL_VALUE(x) ( x & 0xfff ) #define SETVAL_VALUE(x,y) ( ( x & ~0xfff ) | ( y&0xfff ) ) #define GETVAL_MIN_VALUE(x) ( (x>>12) & 0xfff ) #define GETVAL_MAX_VALUE(x) ( x & 0xfff ) #define GETVAL_V_VALUE(x) ( x & 0xfff ) #define SETVAL_V_VALUE(x,y) ( ( x & ~0xfff ) | ( y&0xfff ) ) #define GETVAL_U_VALUE(x) ( (x>>12) & 0xfff ) #define SETVAL_U_VALUE(x,y) ( ( x & ~( 0xfff<<12 ) ) | ( ( y&0xfff )<<12 ) ) #define GETVAL_FRAME_RATE(x) ( x >> 29 ) #define SETVAL_FRAME_RATE(x,y) ( x | ( ( y&0xf ) << 29 ) ) #endif libunicap/cpi/dcam/dcam_v_modes.c0000644000175000017500000001634013164711411017524 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif #include #include #include #include "dcam.h" #include "dcam_functions.h" #include "dcam_format_table.h" #include "dcam_isoch_table.h" #include "dcam_v_modes.h" #include "dcam_offsets.h" #include "1394util.h" #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" /* returns the number of video modes supported by the device described by (node,directory) returns 0 on errors */ int _dcam_count_v_modes( dcam_handle_t dcamhandle, int node, int directory ) { nodeaddr_t addr = dcamhandle->command_regs_base; quadlet_t formats; quadlet_t modes; int count = 0; if( _dcam_read_register( dcamhandle->raw1394handle, node, addr + 0x100, &formats ) < 0 ) { TRACE( "Failed to read formats\n" ); return 0; } if( formats & ( 1 << 31 ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, node, addr + 0x180, &modes ) == 0 ) { int i; for( i = 0; i < 8; i++ ) { if( modes & ( 1<<(31-i) ) ) { count++; /* TRACE( "Mode: %d\n", i ); */ } } } /* TRACE( "format0: %d\n", count ); */ } if( formats & ( 1 << 30 ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, node, addr + 0x180, &modes ) == 0 ) { int i; for( i = 0; i < 8; i++ ) { if( modes & ( 1<<(31-i) ) ) { count++; } } } /* TRACE( "format1: %d\n", count ); */ } if( formats & ( 1 << 29 ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, node, addr + 0x180, &modes ) == 0 ) { int i; for( i = 0; i < 8; i++ ) { if( modes & ( 1<<(31-i) ) ) { count++; } } } /* TRACE( "format2: %d\n", count ); */ } return count; } /* returns index of the mode in _dcam_isoch_table and _dcam_formats_table */ int _dcam_get_mode_index( unsigned int format, unsigned int mode ) { if( mode > 7 ) { return -1; } if( format > 2 ) { return -1; } return (format * 8 ) + mode; }; /* create array of unicap video formats supported by the camera described by (node,directory) input: format_array: allocated memory area format_count: number of entries allocated in format_array output: format_array: initialized table of supported video formats format_count: number of entries actually used in the array */ unicap_status_t _dcam_prepare_format_array( dcam_handle_t dcamhandle, int node, int directory, unicap_format_t *format_array, int *format_count ) { nodeaddr_t addr = dcamhandle->command_regs_base; quadlet_t formats; quadlet_t modes; int current_format=0; int f; if( *format_count < _dcam_count_v_modes( dcamhandle, node, directory ) ) { *format_count = 0; return STATUS_BUFFER_TOO_SMALL; } // read format inquiry register if( _dcam_read_register( dcamhandle->raw1394handle, node, addr + O_FORMAT_INQ, &formats ) < 0 ) { *format_count = 0; return STATUS_FAILURE; } for( f = 0; f < 3; f++ ) { if( formats & ( 1<<(31-f) ) ) { // read mode inquiry register if( _dcam_read_register( dcamhandle->raw1394handle, node, addr + O_MODE_INQ_BASE + (f*4), &modes ) == 0 ) { int i; for( i = 0; i < 8; i++ ) { if( modes & ( 1<<(31-i) ) ) { int index = _dcam_get_mode_index( f, i ); TRACE( "f: %d m: %d index: %d (%s)\n", f, i, index, _dcam_unicap_formats[index].identifier ); TRACE( "size: %d x %d\n", _dcam_unicap_formats[index].size.width, _dcam_unicap_formats[index].size.height ); if (index >0) memcpy( format_array + current_format, &_dcam_unicap_formats[index], sizeof( unicap_format_t ) ); current_format++; } } } } } *format_count = current_format; return STATUS_SUCCESS; } unicap_status_t _dcam_set_mode_and_format( dcam_handle_t dcamhandle, int index ) { int format; int mode; quadlet_t quad; format = index / 8; mode = index % 8; TRACE( "format: %d, mode: %d\n", format, mode ); quad = mode << 29; if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_CUR_MODE, quad )< 0 ) { return STATUS_FAILURE; } quad = format << 29; if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_CUR_FORMAT, quad ) < 0 ) { return STATUS_FAILURE; } return STATUS_SUCCESS; } /* returns the video mode currently set on the camera */ unicap_status_t _dcam_get_current_v_mode( dcam_handle_t dcamhandle, int *mode ) { quadlet_t quad; if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_CUR_MODE, &quad ) < 0 ) { return STATUS_FAILURE; } *mode = quad >> 29; return STATUS_SUCCESS; } /* returns the video format currently set on the camera */ unicap_status_t _dcam_get_current_v_format( dcam_handle_t dcamhandle, int *format ) { quadlet_t quad; if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_CUR_FORMAT, &quad ) < 0 ) { return STATUS_FAILURE; } *format = quad >> 29; return STATUS_SUCCESS; } /* returns the frame rates supported by the mode & format combination currently set on the camera ( return value is of type frame_rate_inq_t.quadlet ) */ quadlet_t _dcam_get_supported_frame_rates( dcam_handle_t dcamhandle ) { int mode, format; unsigned int offset = 0; quadlet_t quad; if( !SUCCESS( _dcam_get_current_v_mode( dcamhandle, &mode ) ) ) { return 0; } if( !SUCCESS( _dcam_get_current_v_format( dcamhandle, &format ) ) ) { return 0; } if( format == 0 ) { if( mode < 7 ) { offset = 0x200 + ( 4*mode ); } } else if( format == 1 ) { if( mode < 8 ) { offset = 0x220 + ( 4*mode ); } } else if( format == 2 ) { if( mode < 8 ) { offset = 0x240 + ( 4 * mode ); } } if( offset == 0 ) // unsupported mode { return 0; } if( !SUCCESS( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + offset, &quad ) ) ) { return 0; } return quad; } libunicap/cpi/dcam/dcam.c0000644000175000017500000007756213164711411016025 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "unicap_helpers.h" #include #include #include #include #include #include #include #include #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif #include #include "dcam.h" #include "dcam_offsets.h" #include "dcam_functions.h" #include "dcam_v_modes.h" #include "dcam_property.h" #include "dcam_capture.h" #include "dcam_busreset.h" #include "unicap_cpi.h" #include "1394util.h" #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" #include #include static unicap_status_t cpi_enumerate_devices( unicap_device_t *device, int index ); static unicap_status_t cpi_open( void **cpi_data, unicap_device_t *device ); static unicap_status_t cpi_close( void *cpi_data ); static unicap_status_t cpi_reenumerate_formats( void *cpi_data, int *count ); static unicap_status_t cpi_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ); static unicap_status_t cpi_set_format( void *cpi_data, unicap_format_t *format ); static unicap_status_t cpi_get_format( void *cpi_data, unicap_format_t *format ); static unicap_status_t cpi_reenumerate_properties( void *cpi_data, int *count ); static unicap_status_t cpi_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ); static unicap_status_t cpi_set_property( void *cpi_data, unicap_property_t *property ); static unicap_status_t cpi_get_property( void *cpi_data, unicap_property_t *property ); static unicap_status_t cpi_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ); static unicap_status_t cpi_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); static unicap_status_t cpi_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); static unicap_status_t cpi_poll_buffer( void *cpi_data, int *count ); static unicap_status_t dcam_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ); extern unicap_format_t _dcam_unicap_formats[]; extern struct _dcam_isoch_mode dcam_isoch_table[]; static struct _unicap_cpi cpi_s = { cpi_version: 1<<16, cpi_capabilities: 0x3ffff, cpi_enumerate_devices: cpi_enumerate_devices, cpi_open: cpi_open, cpi_close: cpi_close, cpi_reenumerate_formats: cpi_reenumerate_formats, cpi_enumerate_formats: cpi_enumerate_formats, cpi_set_format: cpi_set_format, cpi_get_format: cpi_get_format, cpi_reenumerate_properties: cpi_reenumerate_properties, cpi_enumerate_properties: cpi_enumerate_properties, cpi_set_property: cpi_set_property, cpi_get_property: cpi_get_property, cpi_capture_start: dcam_capture_start, cpi_capture_stop: dcam_capture_stop, cpi_queue_buffer: cpi_queue_buffer, cpi_dequeue_buffer: cpi_dequeue_buffer, cpi_wait_buffer: cpi_wait_buffer, cpi_poll_buffer: cpi_poll_buffer, cpi_set_event_notify: dcam_set_event_notify, }; #if ENABLE_STATIC_CPI void unicap_dcam_register_static_cpi( struct _unicap_cpi **cpi ) { *cpi = &cpi_s; } #else unicap_status_t cpi_register( struct _unicap_cpi *reg_data ) { memcpy( reg_data, &cpi_s, sizeof( struct _unicap_cpi ) ); /* reg_data->cpi_version = 1<<16; */ /* reg_data->cpi_capabilities = 0x3ffff; */ /* reg_data->cpi_enumerate_devices = cpi_enumerate_devices; */ /* reg_data->cpi_open = cpi_open; */ /* reg_data->cpi_close = cpi_close; */ /* reg_data->cpi_reenumerate_formats = cpi_reenumerate_formats; */ /* reg_data->cpi_enumerate_formats = cpi_enumerate_formats; */ /* reg_data->cpi_set_format = cpi_set_format; */ /* reg_data->cpi_get_format = cpi_get_format; */ /* reg_data->cpi_reenumerate_properties = cpi_reenumerate_properties; */ /* reg_data->cpi_enumerate_properties = cpi_enumerate_properties; */ /* reg_data->cpi_set_property = cpi_set_property; */ /* reg_data->cpi_get_property = cpi_get_property; */ /* reg_data->cpi_capture_start = dcam_capture_start; */ /* reg_data->cpi_capture_stop = dcam_capture_stop; */ /* reg_data->cpi_queue_buffer = cpi_queue_buffer; */ /* reg_data->cpi_dequeue_buffer = cpi_dequeue_buffer; */ /* reg_data->cpi_wait_buffer = cpi_wait_buffer; */ /* reg_data->cpi_poll_buffer = cpi_poll_buffer; */ /* reg_data->cpi_set_event_notify = dcam_set_event_notify; */ return STATUS_SUCCESS; } #endif//ENABLE_STATIC_CPI int cpi_enumerate_devices( unicap_device_t *device, int index ) { raw1394handle_t raw1394handle; int numcards; struct raw1394_portinfo portinfo[16]; int current_index = 0; int card = 0; /* TRACE( "dcam_enumerate_devices ( i = %d ) \n", index ); */ raw1394handle = raw1394_new_handle(); if( !raw1394handle ) { if( !errno ) { TRACE( "dcam: no kernel support\n" ); return STATUS_NO_DEVICE; } else { TRACE( "dcam: can' t get handle\n" ); return STATUS_NO_DEVICE; } } numcards = raw1394_get_port_info( raw1394handle, portinfo, 16 ); if( !numcards ) { TRACE( "dcam: no 1394 cards!\n" ); raw1394_destroy_handle( raw1394handle ); return STATUS_NO_DEVICE; } else if( numcards < 0 ) { raw1394_destroy_handle( raw1394handle ); return STATUS_NO_DEVICE; } raw1394_destroy_handle( raw1394handle ); // go through all present cards, search for cameras for( card = 0; card < numcards; card++ ) { int nodecount; int node = 0; if( ( raw1394handle = raw1394_new_handle_on_port( card ) ) == 0 ) { return STATUS_NO_DEVICE; } raw1394_set_userdata( raw1394handle, 0 ); TRACE( "dcam: probing card %d\n", card ); nodecount = raw1394_get_nodecount( raw1394handle ); for( node = 0; node < nodecount; node++ ) { int unit_directory_count; int directory; TRACE( "dcam: probing node %d\n", node ); // shortcut since most devices only have 1 unit directory if( _dcam_is_compatible( raw1394handle, node, 0 ) ) { if( index == current_index ) { unicap_status_t status; status = _dcam_get_device_info( raw1394handle, node, 0, device ); if( status == STATUS_SUCCESS ) { TRACE( "found dcam\n" ); // got the device with the index we want raw1394_destroy_handle( raw1394handle ); return status; } else { TRACE( "can not get device info!\n" ); } } current_index++; continue; } unit_directory_count = _dcam_get_directory_count( raw1394handle, node ); if( unit_directory_count <= 1 ) { TRACE( "directory count <= 1 for node: %d\n", node ); continue; // try next device } // scan through all directories of this device for( directory = 1; directory < unit_directory_count; directory++ ) { if( _dcam_is_compatible( raw1394handle, node, directory ) ) { if( index == current_index ) { unicap_status_t status; status = _dcam_get_device_info( raw1394handle, node, directory, device ); if( status == STATUS_SUCCESS ) { // got the device with the index we want raw1394_destroy_handle( raw1394handle ); return status; } } current_index++; } }// for( directory.. }// for( node.. raw1394_destroy_handle( raw1394handle ); }// for( card.. return STATUS_NO_DEVICE; } void *wakeup_routine( void *data ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) data; while( dcamhandle->raw1394handle ) { raw1394_wake_up( dcamhandle->raw1394handle ); sleep( 1 ); } return 0; } int cpi_open( void **cpi_data, unicap_device_t *device ) { dcam_handle_t dcamhandle; unicap_status_t status; int port, node, directory; int i_tmp; char *env; int is_initializing; struct timeval init_timeout; *cpi_data = malloc( sizeof( struct _dcam_handle ) ); if( !*cpi_data ) { return STATUS_NO_MEM; } dcamhandle = (dcam_handle_t) *cpi_data; memset( dcamhandle, 0x0, sizeof( struct _dcam_handle ) ); TIME("dcam_find_device", { status = _dcam_find_device( device, &port, &node, &directory ); if( !SUCCESS( status ) ) { TRACE( "cpi_open: Could not find device\n" ); free( *cpi_data ); return status; } } ) dcamhandle->allocate_bandwidth = 1; if( ( env = getenv( "UNICAP_DCAM_BW_CONTROL" ) ) ) { if( !strncasecmp( "enable", env, strlen( "enable" ) ) ) { dcamhandle->allocate_bandwidth = 0; } } dcamhandle->device_present = 1; dcamhandle->raw1394handle = raw1394_new_handle_on_port( port ); dcamhandle->port = port; dcamhandle->node = node; dcamhandle->directory = directory; dcamhandle->current_frame_rate = -1; if (dcam_juju_probe (dcamhandle)){ TRACE ("JuJu probe: Found JuJu stack\n"); dcamhandle->use_dma = DCAM_DMA_JUJU; } else { dcamhandle->use_dma = DCAM_DMA_VIDEO1394; } dcamhandle->timeout_seconds = 1; // 1 Second timeout default raw1394_set_userdata( dcamhandle->raw1394handle, dcamhandle ); dcamhandle->command_regs_base = _dcam_get_command_regs_base( dcamhandle->raw1394handle, node, _dcam_get_unit_directory_address( dcamhandle->raw1394handle, node, directory ) ); TIME("dcam_prepare_property_table", { _dcam_prepare_property_table( dcamhandle, &dcamhandle->dcam_property_table ); } ); #if UNICAP_THREADS if( pthread_create( &dcamhandle->timeout_thread, NULL, wakeup_routine, dcamhandle ) < 0 ) { TRACE( "FAILED to create timeout_thread!\n" ); dcamhandle->timeout_thread = 0; } #else dcamhandle->timeout_thread = 0; #endif memcpy( &dcamhandle->unicap_device, device, sizeof( unicap_device_t ) ); raw1394_set_bus_reset_handler( dcamhandle->raw1394handle, dcam_busreset_handler ); // power cycle TIME("power_cycle", { _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x610, 0<<31 ); _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x610, 1<<31 ); } ); TIME("initialize", { // Camera initialize _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x0, 1<<31 ); gettimeofday( &init_timeout, NULL ); init_timeout.tv_sec++; is_initializing = 1; while( is_initializing ) { quadlet_t quad; struct timeval ctime; usleep( 100000 ); _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x0, &quad ); gettimeofday( &ctime, NULL ); // wait until either init flag is cleared or timout expired is_initializing = timercmp( &init_timeout, &ctime, > ) && ( quad >> 31 ); } } ); cpi_reenumerate_formats( dcamhandle, &i_tmp ); cpi_reenumerate_properties( dcamhandle, &i_tmp ); ucutil_init_queue( &dcamhandle->input_queue ); ucutil_init_queue( &dcamhandle->output_queue ); return STATUS_SUCCESS; } int cpi_close( void *cpi_data ) { dcam_handle_t dcamhandle = (dcam_handle_t)cpi_data; raw1394handle_t raw1394handle = dcamhandle->raw1394handle; if( !cpi_data ) { return STATUS_SUCCESS; } dcam_capture_stop( cpi_data ); dcamhandle->raw1394handle = 0; #if UNICAP_THREADS if( dcamhandle->timeout_thread ) { pthread_join( dcamhandle->timeout_thread, NULL ); } #endif raw1394_destroy_handle( raw1394handle ); if( dcamhandle->unicap_handle ) { free( dcamhandle->unicap_handle ); } free( dcamhandle ); return STATUS_SUCCESS; } unicap_status_t cpi_reenumerate_formats( void *cpi_data, int *count ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_status_t status; dcamhandle->v_format_count = sizeof( dcamhandle->v_format_array ) / sizeof( unicap_format_t ); status = _dcam_prepare_format_array( dcamhandle, dcamhandle->node, dcamhandle->directory, dcamhandle->v_format_array, &dcamhandle->v_format_count ); if( count ) { *count = dcamhandle->v_format_count; } return status; } int cpi_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ) { dcam_handle_t dcamhandle = (dcam_handle_t)cpi_data; if( index < 0 ) { TRACE( "index < 0 !!!\n" ); return STATUS_INVALID_PARAMETER; } if( index > ( dcamhandle->v_format_count - 1 ) ) { TRACE( "index (%d) > format count\n", index, dcamhandle->v_format_count-1 ); return STATUS_NO_MATCH; } memcpy( format, &dcamhandle->v_format_array[index], sizeof( unicap_format_t ) ); TRACE( "dcam enumerate formats, index: %d id: %s\n", index, format->identifier ); TRACE( "format: %dx%dx%d\n", format->size.width, format->size.height, format->bpp ); return STATUS_SUCCESS; } /* set format and mode on the camera, according to "format" tries to keep current_frame_rate to the actual value. lowers current_frame_rate if it is not available for the current mode or if there is not enough bandwidth for the current frame rate. if current_frame_rate == -1: set to highest returns STATUS_NO_MATCH if "format" is not supported by the camera STATUS_FAILURE if write register fails STATUS_FRAME_RATE_NOT_AVAILABLE if no frame rate is */ int cpi_set_format( void *cpi_data, unicap_format_t *format ) { dcam_handle_t dcamhandle = (dcam_handle_t)cpi_data; int index = 0; int frame_rate; /* frame_rate_inq_t rate_inq; */ quadlet_t quad; unicap_status_t status; while( ( index < dcamhandle->v_format_count ) && ( strcmp( format->identifier, dcamhandle->v_format_array[index].identifier ) ) ) { index++; } if( index == dcamhandle->v_format_count ) { TRACE( "no match, index = %d, count = %d\n", index, dcamhandle->v_format_count ); return STATUS_NO_MATCH; } dcamhandle->current_format_index = index; TRACE( "current_format_index: %d, in identifier: %s out identifier: %s\n", dcamhandle->current_format_index, format->identifier, dcamhandle->v_format_array[index].identifier); for( index = 0; strcmp( _dcam_unicap_formats[index].identifier, format->identifier ); index++ ) { } // check the available bandwidth and set the highest available frame rate if( dcamhandle->current_frame_rate == -1 ) { dcamhandle->current_frame_rate = 5; } // read the frame rate inquiry register for this mode if( !SUCCESS( status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x200 + (index * 4 ), &quad ) ) ) { return status; } for( frame_rate = dcamhandle->current_frame_rate; frame_rate >= 0; frame_rate-- ) { if( _dcam_check_frame_rate_available( quad, frame_rate ) ) { /* int bw_available; */ /* bw_available = _1394util_get_available_bandwidth( dcamhandle->raw1394handle ); */ /* if( bw_available >= dcam_isoch_table[ (index * 6 + frame_rate) ].bytes_per_packet ) */ /* { */ quad = frame_rate << 29; if( SUCCESS( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x600, quad ) ) ) { // frame rate available && enough bandwidth dcamhandle->current_frame_rate = frame_rate; break; } /* else { */ /* TRACE( "failed to set frame rate\n" ); */ /* return STATUS_FAILURE; */ /* } */ /* } */ } } if( dcamhandle->current_frame_rate < 0 ) { return STATUS_FRAME_RATE_NOT_AVAILABLE; } _dcam_set_mode_and_format( dcamhandle, index ); dcamhandle->current_iso_base_index = index * 6; dcamhandle->current_iso_index = index * 6 + dcamhandle->current_frame_rate; /* TRACE( "<-------- set format\n" ); */ return STATUS_SUCCESS; } /* get format currently set on the camera */ unicap_status_t cpi_get_format( void *cpi_data, unicap_format_t *format ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) cpi_data; int mode_index; int format_index; int index; unicap_status_t status; /* int format_count = sizeof( _dcam_unicap_formats ) / sizeof( unicap_format_t ); */ int format_count = 3*8; status = _dcam_get_current_v_mode( dcamhandle, &mode_index ); if( !SUCCESS( status ) ) { return status; } status = _dcam_get_current_v_format( dcamhandle, &format_index ); if( !SUCCESS( status ) ) { return status; } index = format_index * 8 + mode_index; TRACE( "get format: mode_index: %d format_index: %d\n", mode_index, format_index ); if( index < format_count ) { memcpy( format, &_dcam_unicap_formats[index], sizeof( unicap_format_t ) ); TRACE( "format->buffer_size: %d\n", format->buffer_size ); } else { return STATUS_FAILURE; } return STATUS_SUCCESS; } unicap_status_t cpi_reenumerate_properties( void *cpi_data, int *count ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_status_t status = STATUS_SUCCESS; int i; quadlet_t feature_hi, feature_lo; *count = 0; if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x404, &feature_hi ) < 0 ) { return STATUS_FAILURE; } if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x408, &feature_lo ) ) { return STATUS_FAILURE; } dcamhandle->feature_hi = feature_hi; dcamhandle->feature_lo = feature_lo; for( i = 0; dcamhandle->dcam_property_table[i].id != DCAM_PPTY_END; i++ ) { if( ( dcamhandle->dcam_property_table[i].feature_hi_mask & feature_hi ) || ( dcamhandle->dcam_property_table[i].feature_lo_mask & feature_lo ) ) { if( SUCCESS( dcamhandle->dcam_property_table[i].init_function( dcamhandle, 0, &dcamhandle->dcam_property_table[i] ) ) ) { (*count)++; } } } return status; } unicap_status_t cpi_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; int i; int current = 0; unicap_status_t status = STATUS_NO_MATCH; if( index < 0 ) { return STATUS_INVALID_PARAMETER; } for( i = 0; dcamhandle->dcam_property_table[i].id != DCAM_PPTY_END; i++ ) { if( ( dcamhandle->dcam_property_table[i].feature_hi_mask & dcamhandle->feature_hi ) || ( dcamhandle->dcam_property_table[i].feature_lo_mask & dcamhandle->feature_lo ) ) { if( current == index ) { unicap_copy_property( property, &dcamhandle->dcam_property_table[i].unicap_property ); status = STATUS_SUCCESS; break; } current++; } } return status; } unicap_status_t cpi_set_property( void *cpi_data, unicap_property_t *property ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_status_t status = STATUS_NO_MATCH; int i; for( i = 0; dcamhandle->dcam_property_table[ i ].id != DCAM_PPTY_END; i++ ) { if( !strcmp( property->identifier, dcamhandle->dcam_property_table[ i ].unicap_property.identifier ) ) { dcam_property_t *dcam_property = &dcamhandle->dcam_property_table[ i ]; status = dcamhandle->dcam_property_table[ i ].set_function( dcamhandle, property, dcam_property ); break; } } return status; } unicap_status_t cpi_get_property( void *cpi_data, unicap_property_t *property ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_status_t status = STATUS_NO_MATCH; int i; for( i = 0; dcamhandle->dcam_property_table[ i ].id != DCAM_PPTY_END; i++ ) { if( !strcmp( property->identifier, dcamhandle->dcam_property_table[ i ].unicap_property.identifier ) ) { dcam_property_t *dcam_property = &dcamhandle->dcam_property_table[ i ]; unicap_copy_property_nodata( property, &dcam_property->unicap_property ); status = dcamhandle->dcam_property_table[ i ].get_function( dcamhandle, property, dcam_property ); break; } } return status; } unicap_status_t dcam_capture_start( void *cpi_data ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; int channel; quadlet_t quad; int retries = 1; allocate: if( ( channel = _1394util_find_free_channel( dcamhandle->raw1394handle ) ) < 0 ) { TRACE( "dcam.cpi: failed to allocate channel\n"); return STATUS_INSUFFICIENT_RESOURCES; } if( dcamhandle->allocate_bandwidth ) { if( STATUS_SUCCESS != (_1394util_allocate_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ) ) ) { TRACE( "dcam.cpi: failed to allocate bandwidth\n" ); _1394util_free_channel( dcamhandle->raw1394handle, channel ); if( retries-- ) { TRACE( "trying a busreset\n" ); raw1394_reset_bus_new( dcamhandle->raw1394handle, RAW1394_SHORT_RESET ); sleep( 1 ); // waiting one second to allow devices to reallocate BW goto allocate; } return STATUS_INSUFFICIENT_BANDWIDTH; } else { TRACE( "BW_allocate: success\n" ); } } TRACE( "BW allocated\n" ); if( dcam_isoch_table[dcamhandle->current_iso_index].min_speed <= S400 ) { quad = ( channel << 28 ) | ( S400 << 24 ); } else { quad = ( channel << 28 ) | ( dcam_isoch_table[dcamhandle->current_iso_index].min_speed << 24 ); } if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x60c, quad ) < 0 ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); TRACE( "failed to write iso_channel register\n" ); return STATUS_FAILURE; } if( dcamhandle->allocate_bandwidth ) { dcamhandle->bandwidth_allocated = dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet; } dcamhandle->channel_allocated = channel; // enable iso transmission if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_ISO_CTRL, 1 << 31 ) < 0 ) { TRACE( "failed to write iso enable register\n" ); return STATUS_FAILURE; } TRACE( "bytes per pkt: %d idx: %d, channel: %d, frame rate: %d\n", dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet, dcamhandle->current_iso_index, channel, dcamhandle->current_frame_rate); if (dcamhandle->use_dma == DCAM_DMA_JUJU){ dcamhandle->buffer_size = dcam_isoch_table[ dcamhandle->current_iso_index ]. bytes_per_frame; if (!SUCCESS (dcam_juju_setup (dcamhandle))){ TRACE ("Failed to setup juju\n"); } if (!SUCCESS (dcam_juju_prepare_iso (dcamhandle))){ TRACE ("Failed to prepare juju iso\n"); } if (!SUCCESS (dcam_juju_start_iso (dcamhandle))){ TRACE ("Failed to start juju iso\n"); } dcamhandle->dma_capture_thread_quit = 0; #if UNICAP_THREADS pthread_create( &dcamhandle->dma_capture_thread, NULL, dcam_juju_capture_thread, dcamhandle ); #endif } else if( dcamhandle->use_dma == DCAM_DMA_VIDEO1394) { // use video1394 for isoch reception dcamhandle->buffer_size = dcam_isoch_table[ dcamhandle->current_iso_index ].bytes_per_frame; TRACE( "dcamhandle->buffer_size: %d\n", dcamhandle->buffer_size ); TRACE( "dcamhandle->current_iso_index: %d\n", dcamhandle->current_iso_index ); if( !SUCCESS( _dcam_dma_setup( dcamhandle ) ) ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_ISO_CTRL, 0 ); TRACE( "failed to setup DMA\n" ); return STATUS_FAILURE; } dcamhandle->dma_capture_thread_quit = 0; #if UNICAP_THREADS pthread_create( &dcamhandle->dma_capture_thread, NULL, dcam_dma_capture_thread, dcamhandle ); #endif } else { // use raw1394 packet_per_buffer for isoch reception if( raw1394_iso_recv_init( dcamhandle->raw1394handle, dcam_iso_handler, 1000, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet, channel, #ifdef RAW1394_1_1_API RAW1394_DMA_PACKET_PER_BUFFER, #endif 10 ) < 0 ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); // disable iso transmission _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_ISO_CTRL, 0 ); TRACE( "raw1394_iso_recv_init failed\n" ); return STATUS_FAILURE; } if( raw1394_iso_recv_start( dcamhandle->raw1394handle, -1, -1, -1 ) < 0 ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + O_ISO_CTRL, 0 ); return STATUS_FAILURE; } dcamhandle->wait_for_sy = 1; dcamhandle->buffer_size = dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_frame; dcamhandle->current_buffer_offset = 0; } dcamhandle->capture_running = 1; return STATUS_SUCCESS; } unicap_status_t dcam_capture_stop( void *cpi_data ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_status_t status = STATUS_SUCCESS; if( dcamhandle->capture_running ) { if( !dcamhandle->use_dma ) { raw1394_iso_stop( dcamhandle->raw1394handle ); } else { dcamhandle->dma_capture_thread_quit = 1; #if UNICAP_THREADS // send a signal to interrupt the ioctl pthread_kill( dcamhandle->dma_capture_thread, SIGUSR1 ); pthread_join( dcamhandle->dma_capture_thread, NULL ); #endif if( dcamhandle->use_dma == DCAM_DMA_VIDEO1394) { _dcam_dma_unlisten( dcamhandle ); _dcam_dma_free( dcamhandle ); } else { dcam_juju_shutdown (dcamhandle); } } if( dcamhandle->device_present ) { _1394util_free_channel( dcamhandle->raw1394handle, dcamhandle->channel_allocated ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcamhandle->bandwidth_allocated ); } } else { TRACE( "capture not running!\n" ); status = STATUS_CAPTURE_ALREADY_STOPPED; } // Disable isochronous transmission _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x614, 0 ); dcamhandle->capture_running = 0; // if a buffer is in use, return it to the input queue if( dcamhandle->current_buffer ) { ucutil_insert_front_queue( &dcamhandle->input_queue, dcamhandle->current_buffer ); dcamhandle->current_buffer = 0; } return status; } unicap_status_t cpi_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_queue_t *entry; entry = malloc( sizeof( unicap_queue_t ) ); if( !entry ) { return STATUS_INSUFFICIENT_RESOURCES; } entry->data = buffer; ucutil_insert_back_queue( &dcamhandle->input_queue, entry ); return STATUS_SUCCESS; } unicap_status_t cpi_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { dcam_handle_t dcamhandle = (dcam_handle_t)cpi_data; unicap_queue_t *entry; if( dcamhandle->capture_running ) { return STATUS_IS_RECEIVING; } entry = ucutil_get_front_queue( &dcamhandle->input_queue ); if( !entry ) { entry = ucutil_get_front_queue( &dcamhandle->output_queue ); } if( !entry ) { return STATUS_NO_BUFFERS; } (*buffer) = entry->data; free( entry ); return STATUS_SUCCESS; } unicap_status_t cpi_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { dcam_handle_t dcamhandle = (dcam_handle_t) cpi_data; unicap_status_t status = STATUS_SUCCESS; if( !dcamhandle->output_queue.next && !dcamhandle->capture_running ) { TRACE( "capture stopped\n" ); return STATUS_IS_STOPPED; } #if !UNICAP_THREADS dcam_dma_wait_buffer( dcamhandle ); #endif if( dcamhandle->output_queue.next ) { unicap_queue_t *first_entry; unicap_data_buffer_t *returned_buffer; first_entry = ucutil_get_front_queue( &dcamhandle->output_queue ); (*buffer) = first_entry->data; returned_buffer = *buffer; unicap_copy_format( &returned_buffer->format, &dcamhandle->v_format_array[dcamhandle->current_format_index] ); free( first_entry ); } else { if( dcamhandle->input_queue.next || dcamhandle->current_buffer ) { unicap_queue_t *first_entry; struct timeval timeout_time, cur_time; unicap_data_buffer_t *returned_buffer; if( gettimeofday( &timeout_time, NULL ) < 0 ) { return STATUS_FAILURE; } timeout_time.tv_sec += dcamhandle->timeout_seconds; while( !dcamhandle->output_queue.next ) { // raw1394_loop_iterate is waked regularly by a seperate thread ( every 500ms ) if( gettimeofday( &cur_time, NULL ) < 0 ) { return STATUS_FAILURE; } if( timercmp( &cur_time, &timeout_time, > ) ) { // restart DMA on timeout // There seems to be a bug in the video1394 driver that causes the // DMA to lock up without reason. We try to restart the DMA and return // STATUS_TIMEOUT to notify the application // TODO: find out if this is fixed in recent kernels dcam_capture_stop( dcamhandle ); dcam_capture_start( dcamhandle ); return STATUS_TIMEOUT; } // TODO: Implement semaphore based waiting { // raw1394_loop_iterate is called in a seperate thread usleep( 1000 ); } } first_entry = ucutil_get_front_queue( &dcamhandle->output_queue ); *buffer = first_entry->data; returned_buffer = *buffer; unicap_copy_format( &returned_buffer->format, &dcamhandle->v_format_array[dcamhandle->current_format_index] ); free( first_entry ); } else { return STATUS_NO_BUFFERS; } } return status; } unicap_status_t cpi_poll_buffer( void *cpi_data, int *count ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) cpi_data; int buffers = 0; buffers = ucutil_queue_get_size( &dcamhandle->output_queue ); *count = buffers; return STATUS_SUCCESS; } unicap_status_t dcam_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) cpi_data; dcamhandle->event_callback = func; dcamhandle->unicap_handle = unicap_handle; return STATUS_SUCCESS; } libunicap/cpi/dcam/dcam_v_modes.h0000644000175000017500000000270513164711411017531 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_V_MODES_H__ #define __DCAM_V_MODES_H__ #include unicap_status_t _dcam_prepare_format_array( dcam_handle_t, int node, int directory, unicap_format_t *format_array, int *format_count ); int _dcam_count_v_modes( dcam_handle_t, int node, int directory ); int _dcam_get_mode_index( unsigned int format, unsigned int mode ); unicap_status_t _dcam_set_mode_and_format( dcam_handle_t dcamhandle, int index ); unicap_status_t _dcam_get_current_v_mode( dcam_handle_t dcamhandle, int *mode ); unicap_status_t _dcam_get_current_v_format( dcam_handle_t dcamhandle, int *format ); quadlet_t _dcam_get_supported_frame_rates( dcam_handle_t dcamhandle ); #endif//__DCAM_V_MODES_H__ libunicap/cpi/dcam/dcam_isoch_table.h0000644000175000017500000001314213164711411020346 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_ISOCH_TABLE_H__ #define __DCAM_ISOCH_TABLE_H__ #include struct _dcam_isoch_mode dcam_isoch_table[]= { // Format 0 { -1, -1, -1 }, // Mode0, 1.875 { -1, -1, -1 }, // Mode0, 3.75 { 160*120*3, 20*3, S100 }, // mode0, 7.5 { 160*120*3, 40*3, S100 }, // mode0, 15 { 160*120*3, 80*3, S100 }, // mode0, 30 { 160*120*3, 160*3, S100 }, // Mode0, 60 {320*240*2, 20*2, S100 }, // Mode1, 1.875 //6 {320*240*2, 40*2, S100 }, //3.75 {320*240*2, 80*2, S100 }, //7.5 {320*240*2, 160*2, S100 }, //15 {320*240*2, 320*2, S100 }, //30 {320*240*2, 640*2, S200 }, // 60 {640*480*1.5, 80*1.5, S100 }, // Mode2, 1.875 //12 {640*480*1.5, 160*1.5, S100 },//3.75 {640*480*1.5, 320*1.5, S100 },//7.5 {640*480*1.5, 640*1.5, S100 },//15 {640*480*1.5, 1280*1.5, S200 },//30 {640*480*1.5, 2560*1.5, S400 }, // 60 {640*480*2, 80*2, S100 }, // Mode3, 1.875 //18 {640*480*2, 160*2, S100 },//3.75 {640*480*2, 320*2, S100 },//7.5 {640*480*2, 640*2, S200 },//15 {640*480*2, 1280*2, S400 },//30 {640*480*2, 2560*2, S800 }, // 60 {640*480*3, 80*3, S100 }, // Mode4 {640*480*3, 160*3, S100 },//3.75 {640*480*3, 320*3, S100 },//7.5 {640*480*3, 640*3, S200 },//15 {640*480*3, 1280*3, S400 },//30 {640*480*3, 2560*3, S800 },//60 {640*480, 80, S100 }, // Mode5 {640*480, 160, S100 },//3.75 {640*480, 320, S100 },//7.5 {640*480, 640, S100 },//15 {640*480, 1280, S200 },//30 {640*480, 2560, S400 },//60 { -1, -1, -1}, // Mode6 {640*480*2, 160*2, S100}, //3.75 {640*480*2, 320*2, S100}, //7.5 {640*480*2, 640*2, S200}, //15 {640*480*2, 1280*2, S400}, //30 {640*480*2, 2560*2, S800}, { -1,-1,-1}, //Mode7 { -1,-1,-1}, //Mode7 { -1,-1,-1}, //Mode7 { -1,-1,-1}, //Mode7 { -1,-1,-1}, //Mode7 { -1,-1,-1}, //Mode7 // Format 1 { -1,-1,-1}, //Mode0 {800*600*2, 250*2, S100}, //3.75 {800*600*2, 500*2, S100}, //7.5 {800*600*2, 1000*2, S200}, //15 {800*600*2, 2000*2, S400}, //30 {800*600*2, 4000*2, S800}, { -1,-1,-1}, //Mode1 { -1,-1,-1}, {800*600*3, 500*3, S200}, //7.5 {800*600*3, 1000*3, S400}, //15 {800*600*3, 2000*3, S800}, {800*600*3, 4000*3, S1600}, { -1,-1,-1}, //Mode2 { -1,-1,-1}, {800*600, 500, S100}, //7.5 {800*600, 1000, S100}, //15 {800*600, 2000, S200}, //30 {800*600, 4000, S400}, //60 {1024*768*2, 192*2, S100}, //1.875 Mode3 {1024*768*2, 384*2, S100}, //3.75 {1024*768*2, 768*2, S200}, //7.5 {1024*768*2, 1536*2, S400}, //15 {1024*768*2, 3072*2, S800}, {1024*768*2, 6144*2, S1600}, {1024*768*3, 192*3, S100}, //1.875 Mode4 {1024*768*3, 384*3, S200}, //3.75 {1024*768*3, 768*3, S400}, //7.5 {1024*768*3, 1536*3, S800}, //15 {1024*768*3, 3072*3, S1600}, //30 {1024*768*3, 6144*3, S3200}, {1024*768, 192, S100}, //1.875 Mode4 {1024*768, 384, S100}, //3.75 {1024*768, 768, S100}, //7.5 {1024*768, 1536, S200}, //15 {1024*768, 3072, S400}, //30 {1024*768, 6144, S800}, { -1,-1,-1}, //Mode6 {800*600*2, 250*2, S100}, //3.75 {800*600*2, 500*2, S100}, //7.5 {800*600*2, 1000*2, S200}, //15 {800*600*2, 2000*2, S400}, //30 {800*600*2, 4000*2, S800}, {1024*768*2, 192*2, S100}, //1.875 Mode7 {1024*768*2, 384*2, S100}, //3.75 {1024*768*2, 768*2, S200}, //7.5 {1024*768*2, 1536*2, S400}, //15 {1024*768*2, 3072*2, S800}, {1024*768*2, 6144*2, S1600}, //Format 2 {1280*960*2, 320*2, S100}, //1.875 Mode0 {1280*960*2, 640*2, S200}, //3.75 {1280*960*2, 1280*2, S400}, {1280*960*2, 2560*2, S800}, {1280*960*2, 5120*2, S1600}, {1280*960*2, 10240*2, S3200}, {1280*960*3, 320*3, S100}, //1.875 Mode1 {1280*960*3, 640*3, S200}, //3.75 {1280*960*3, 1280*3, S400}, {1280*960*3, 2560*3, S800}, {1280*960*3, 5120*3, S1600}, {1280*960*3, 10240*3, S3200}, {1280*960, 320, S100}, //1.875 Mode2 {1280*960, 640, S100}, //3.75 {1280*960, 1280, S200}, {1280*960, 2560, S400}, {1280*960, 5120, S800}, {1280*960, 10240, S1600}, {1600*1200*2, 500*2, S100}, //1.875 //Mode3 {1600*1200*2, 1000*2, S200}, //3.75 {1600*1200*2, 2000*2, S400}, //7.5 {1600*1200*2, 4000*2, S800}, {1600*1200*2, 8000*2, S1600}, {1600*1200*2, 16000*2, S3200}, {1600*1200*3, 500*3, S200}, //1.875 //Mode4 {1600*1200*3, 1000*3, S400}, //3.75 {1600*1200*3, 2000*3, S800}, {1600*1200*3, 4000*3, S1600}, {1600*1200*3, 8000*3, S3200}, { -1,-1,-1}, {1600*1200, 500, S100}, //1.875 //Mode5 {1600*1200, 1000, S100}, //3.75 {1600*1200, 2000, S200}, //7.5 {1600*1200, 4000, S400}, //7.5 {1600*1200, 8000, S800}, {1600*1200, 16000, S1600}, {1280*960*2, 320*2, S100}, //1.875 Mode6 {1280*960*2, 640*2, S200}, //3.75 {1280*960*2, 1280*2, S400}, {1280*960*2, 2560*2, S800}, {1280*960*2, 5120*2, S1600}, {1280*960*2, 10240*2, S3200}, {1600*1200*2, 500*2, S100}, //1.875 //Mode7 {1600*1200*2, 1000*2, S200}, //3.75 {1600*1200*2, 2000*2, S400}, //7.5 {1600*1200*2, 4000*2, S800}, {1600*1200*2, 8000*2, S1600}, {1600*1200*2, 16000*2, S3200}, }; #endif//__DCAM_ISOCH_TABLE_H__ libunicap/cpi/dcam/1394util.c0000644000175000017500000003213313164711411016400 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include // for ntohl #include #ifdef RAW1394_1_1_API #include #include #endif #ifdef RAW1394_1_0_API #include #include #endif #include #include #include #include "1394util.h" #include #if DCAM_DEBUG #define DEBUG #endif #include #define MAXTRIES 20 #define DELAY 1000000 #define EXTCODE_COMPARE_SWAP 0x2 #define MAX_BANDWIDTH 0x1333 // Check this! Should be 0x1000 ??? int cooked1394_read( raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *buffer ) { int retval, i; for( i=0; i < MAXTRIES; i++ ) { retval = raw1394_read( handle, node, addr, length, buffer ); if( retval >= 0 ) { return retval; /* Everything is OK */ } if( errno != EAGAIN ) { break; } /* usleep(DELAY); */ } #ifdef DEBUG perror("Error while reading from IEEE1394: "); #endif return retval; } int cooked1394_write( raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *data) { int retval, i; for( i=0; i < MAXTRIES; i++ ) { /* usleep( DELAY ); */ sleep( 1 ); retval = raw1394_write( handle, node, addr, length, data ); if( retval >= 0 ) { return retval; /* Everything is OK */ } if( errno != EAGAIN ){ break; } } #ifdef DEBUG perror( "Error while writing to IEEE1394: " ); #endif return retval; } /* * Obtain the global unique identifier of a node from its configuration ROM. * The GUID can also be read from a filled out Rom_info structure, but this * method is of course faster than reading the whole configuration ROM and can * for instance be used to obtain a hash key for caching Rom_info structures * in memory. * IN: phyID: Physical ID of the node to read from * hi: Pointer to an integer which should receive the HI quadlet * hi: Pointer to an integer which should receive the LOW quadlet */ unsigned long long get_guid(raw1394handle_t handle, int phyID ) { unsigned int hiquad; unsigned int loquad; unsigned long long guid = 0; if ( cooked1394_read( handle, 0xffC0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x0C, 4, &hiquad ) < 0 ) { return 0; } if ( cooked1394_read( handle, 0xffC0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x10, 4, &loquad ) < 0 ) { return 0; } hiquad = ntohl( hiquad ); loquad = ntohl( loquad ); guid = ( ( unsigned long long ) hiquad ) << 32; guid += loquad; return guid; } unsigned int get_unit_spec_ID( raw1394handle_t handle, int phyID ) { unsigned int unit_dir_offset; unsigned int spec_ID; if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24, 4, &unit_dir_offset ) < 0 ) { TRACE( "failed to read unit_dir _offset\n" ); return 0; } unit_dir_offset = ntohl( unit_dir_offset ); unit_dir_offset &= 0x00ffffff; TRACE( "unit_dir_offset: %x\n", unit_dir_offset ); if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24 + unit_dir_offset + 0x8, 4, &spec_ID ) < 0 ) { return 0; } spec_ID = ntohl( spec_ID ); spec_ID &= 0x00ffffff; return spec_ID; } unsigned int get_unit_sw_version( raw1394handle_t handle, int phyID ) { unsigned int unit_dir_offset; unsigned int sw_version; if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24, 4, &unit_dir_offset ) < 0 ) { TRACE( "failed to read unit_dir _offset\n" ); return 0; } unit_dir_offset = ntohl( unit_dir_offset ); unit_dir_offset &= 0x00ffffff; TRACE( "unit_dir_offset: %x\n", unit_dir_offset ); if( cooked1394_read( handle, 0xffc0 | phyID, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x24 + unit_dir_offset + 0xc, 4, &sw_version ) < 0 ) { return 0; } sw_version = ntohl( sw_version ); sw_version &= 0x00ffffff; return sw_version; } /* allocate the first free channel for isochronous transmission using compare & swap returns: < 0 if channel could not be allocated or the allocated channel */ int _1394util_find_free_channel( raw1394handle_t raw1394handle ) { quadlet_t buffer; int channel = -1; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_CHANNELS_AVAILABLE_LO\n" ); return -1; } buffer = ntohl( buffer ); for( channel = 0; ( !( buffer & ( 1 << channel ) ) ) && channel < 32; channel++ ) { } if( channel > 31 ) // none found in the lower range { if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_CHANNELS_AVAILABLE_HI\n" ); return -1; } buffer = ntohl( buffer ); for( channel = 0; ( !( buffer & ( 1< 31 if( channel > 63 ) { TRACE( "No free channel found\n" ); return -1; } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer & ~( 1< raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { TRACE( "Channel allocation failed\n" ); return -1; } // is the following thread safe? I do not think so! if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to read back available channels\n" ); return -1; } if( buffer != data ) { TRACE( "Validation of channel failed\n" ); return -1; } } return channel; } /* free a channel */ unicap_status_t _1394util_free_channel( raw1394handle_t raw1394handle, int channel ) { quadlet_t buffer; if( 0 <= cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { int channel_bit = channel > 31 ? channel - 32 : channel; quadlet_t data, arg, result; buffer = htonl( buffer ); if( buffer & ( 1< raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { TRACE( "Failed to free channel\n" ); return STATUS_FAILURE; } if( arg != htonl( buffer ) ) { TRACE( "Free channel validation failed\n" ); return STATUS_FAILURE; } return STATUS_SUCCESS; } TRACE( "Read failed\n" ); return STATUS_FAILURE; } /* try to allocate channel on the bus returns: status */ unicap_status_t _1394util_allocate_channel( raw1394handle_t raw1394handle, int channel ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_CHANNELS_AVAILABLE_LO\n" ); return STATUS_FAILURE; } buffer = ntohl( buffer ); if( channel > 31 ) // none found in the lower range { if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_CHANNELS_AVAILABLE_HI\n" ); return -1; } buffer = ntohl( buffer ); }//if( channel > 31 if( channel > 63 ) { TRACE( "Channel number too high\n" ); return STATUS_INVALID_PARAMETER; } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer & ~( 1< raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { TRACE( "Channel allocation failed\n" ); return STATUS_FAILURE; } if( arg != buffer ) { TRACE( "Allocate channel validation failed\n" ); return STATUS_FAILURE; } } return STATUS_SUCCESS; } unicap_status_t _1394util_allocate_bandwidth( raw1394handle_t raw1394handle, int bandwidth ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_BANDWIDTH_AVAILABLE\n" ); return STATUS_FAILURE; } buffer = ntohl( buffer ); if( (int)(buffer - bandwidth) < 0 ) { TRACE( "Insufficient bandwidth\n" ); return STATUS_FAILURE; } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer - bandwidth ); if( 0 > raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { TRACE( "Failed to allocate bandwidth\n" ); return STATUS_FAILURE; } if( arg != htonl( buffer ) ) { TRACE( "Allocate bandwidth validation failed\n" ); return STATUS_FAILURE; } } return STATUS_SUCCESS; } /* free bandwidth no checking if more bw than allocated is freed! */ int _1394util_free_bandwidth( raw1394handle_t raw1394handle, int bandwidth ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_BANDWIDTH_AVAILABLE\n" ); return STATUS_FAILURE; } buffer = ntohl( buffer ); TRACE( "Available bandwidth: 0x%x ( %d )\n", buffer, buffer ); if( (int)(buffer + bandwidth) > MAX_BANDWIDTH ) { // just a warning! TRACE( "Freeing of bandwidth gives more than the maximum allowed ( or the bus is > 400Mbps )\n" ); } else { quadlet_t data, arg, result; arg = htonl( buffer ); data = htonl( buffer + bandwidth ); if( 0 > raw1394_lock( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, EXTCODE_COMPARE_SWAP, data, arg, &result ) ) { TRACE( "Failed to allocate bandwidth\n" ); return STATUS_FAILURE; } if( arg != htonl( buffer ) ) { TRACE( "Allocate bandwidth validation failed: arg = %x, buffer = %x\n", arg, htonl( buffer ) ); return STATUS_FAILURE; } } return STATUS_SUCCESS; } /* return the bw available on the bus. for convenience only, value could change any time */ int _1394util_get_available_bandwidth( raw1394handle_t raw1394handle ) { quadlet_t buffer; if( 0 > cooked1394_read( raw1394handle, raw1394_get_irm_id( raw1394handle ), CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, sizeof( quadlet_t ), &buffer ) ) { TRACE( "Failed to get CSR_BANDWIDTH_AVAILABLE\n" ); return -1; } buffer = ntohl( buffer ); return buffer; } unsigned long bswap( unsigned long v ) { unsigned long r; r = ( v>>24 ) | ( ( ( v>>16 ) & 0xff ) << 8 ) | ( ( ( v>>8 ) & 0xff ) << 16 ) | ( ( ( v ) & 0xff ) << 24 ); return r; } quadlet_t bitswap( quadlet_t value ) { quadlet_t tmp = 0; int i; for( i = 0; i < 32; i++ ) { tmp |= ( ( ( value >>( 31-i ) ) & 1 ) << i ); } return tmp; } libunicap/cpi/dcam/dcam_property.h0000644000175000017500000001531213164711411017757 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_PROPERTY_H__ #define __DCAM_PROPERTY_H__ unicap_status_t _dcam_prepare_property_table( dcam_handle_t dcamhandle, dcam_property_t **property_table ); unicap_status_t dcam_set_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_frame_rate_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_white_balance_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_frame_rate_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_white_balance_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_init_shutter_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_brightness_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_white_balance_mode_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_white_balance_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_frame_rate_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_rw_register_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_init_timeout_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_get_timeout_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_timeout_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_init_gpio_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_set_gpio_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_gpio_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_init_software_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_set_software_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_software_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_strobe_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_strobe_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_strobe_duration_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_strobe_duration_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_strobe_delay_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_strobe_delay_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_strobe_polarity_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_get_strobe_polarity_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_init_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_get_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_init_enable_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ); unicap_status_t dcam_get_enable_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); unicap_status_t dcam_set_enable_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); int _dcam_check_frame_rate_available( quadlet_t quad, int rate ); dcam_property_t *dcam_copy_property( dcam_property_t *dest, dcam_property_t *src ); #endif//__DCAM_PROPERTY_H__ libunicap/cpi/dcam/dcam_juju.h0000644000175000017500000000142313164711411017046 0ustar zmoelnigzmoelnig#ifndef __DCAM_JUJU_H__ #define __DCAM_JUJU_H__ typedef struct dcam_juju_buffer dcam_juju_buffer_t; struct dcam_juju_buffer { size_t size; struct fw_cdev_iso_packet *packets; }; int dcam_juju_probe (dcam_handle_t dcamhandle); unicap_status_t __HIDDEN__ dcam_juju_setup (dcam_handle_t dcamhandle); unicap_status_t dcam_juju_shutdown (dcam_handle_t dcamhandle); unicap_status_t dcam_juju_prepare_iso (dcam_handle_t dcamhandle); unicap_status_t dcam_juju_start_iso (dcam_handle_t dcamhandle); unicap_status_t dcam_juju_queue_buffer (dcam_handle_t dcamhandle, int index); unicap_status_t dcam_juju_dequeue_buffer (dcam_handle_t dcamhandle, int *index, uint32_t *cycle_time, int *packet_discont); void *dcam_juju_capture_thread( void *arg ); #endif//__DCAM_JUJU_H__ libunicap/cpi/dcam/dcam_functions.h0000644000175000017500000000544113164711411020105 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_FUNCTIONS_H__ #define __DCAM_FUNCTIONS_H__ #include #ifdef RAW1394_1_1_API #include #endif #ifdef RAW1394_1_0_API #include #endif #include int _dcam_read_register( raw1394handle_t raw1394handle, int node, nodeaddr_t address, quadlet_t *value ); int _dcam_write_register( raw1394handle_t raw1394handle, int node, nodeaddr_t address, quadlet_t value ); int _dcam_get_directory_count( raw1394handle_t raw1394handle, int node ); nodeaddr_t _dcam_get_unit_directory_address( raw1394handle_t raw1394handle, int node, int directory ); nodeaddr_t _dcam_calculate_address( raw1394handle_t raw1394handle, int node, nodeaddr_t addr, quadlet_t key ); nodeaddr_t _dcam_get_unit_dependent_directory_address( raw1394handle_t raw1394handle, int node, int directory ); unsigned int _dcam_get_spec_ID( raw1394handle_t raw1394handle, int node, nodeaddr_t unit_directory_addr ); unsigned int _dcam_get_sw_version( raw1394handle_t raw1394handle, int node, nodeaddr_t unit_directory_addr ); nodeaddr_t _dcam_get_command_regs_base( raw1394handle_t raw1394handle, int node, nodeaddr_t unit_dependend_directory_addr ); int _dcam_get_vendor_id( raw1394handle_t raw1394handle, int node, int directory, unsigned long *vendor_id ); int _dcam_get_model_id( raw1394handle_t raw1394handle, int node, int directory, unsigned long *model_id_hi, unsigned long *model_id_lo ); int _dcam_read_name_leaf( raw1394handle_t raw1394handle, int node, nodeaddr_t addr, char *buffer, size_t *buffer_len ); int _dcam_is_compatible( raw1394handle_t raw1394handle, int node, int directory ); void _dcam_create_device_identifier( char *buffer, size_t size, char *vendor_name, char *model_name, unsigned long model_id_hi, unsigned long model_id_lo ); unicap_status_t _dcam_get_device_info( raw1394handle_t raw1394handle, int node, int directory, unicap_device_t *device ); unicap_status_t _dcam_find_device( unicap_device_t *device, int *port, int *node, int *directory ); #endif //__DCAM_FUNCTIONS_H__ libunicap/cpi/dcam/dcam_format_table.h0000644000175000017500000003071513164711411020536 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_FORMAT_TABLE_H__ #define __DCAM_FORMAT_TABLE_H__ #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)a))+(((unsigned int)b)<<8)+(((unsigned int)c)<<16)+(((unsigned int)d)<<24)) #include "dcam.h" unicap_format_t _dcam_unicap_formats[] = { // format 0 { identifier: "YUV(4:4:4) 160x120", size: { x: 0, y: 0, width: 160, height: 120}, min_size: { x: 0, y: 0, width: 160, height: 120}, max_size: { x: 0, y: 0, width: 160, height: 120}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 24, fourcc: FOURCC('Y','4','4','4'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 160*120*3 }, { identifier: "YUV(4:2:2) 320x240", size: { x: 0, y: 0, width: 320, height: 240}, min_size: { x: 0, y: 0, width: 320, height: 240}, max_size: { x: 0, y: 0, width: 320, height: 240}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('U','Y','V','Y'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 320*240*2 }, { identifier: "YUV(4:1:1) 640x480", size: { x: 0, y: 0, width: 640, height: 480}, min_size: { x: 0, y: 0, width: 640, height: 480}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 12, fourcc: FOURCC('Y','4','1','1'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 640*480 * 1.5 }, { identifier: "YUV(4:2:2) 640x480", size: { x: 0, y: 0, width: 640, height: 480}, min_size: { x: 0, y: 0, width: 640, height: 480}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('U','Y','V','Y'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 640*480*2 }, { identifier: "RGB 640x480", size: { x: 0, y: 0, width: 640, height: 480}, min_size: { x: 0, y: 0, width: 640, height: 480}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 24, fourcc: FOURCC('R','G','B','3'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 640*480*3 }, { identifier: "Y(Mono) 640x480", size: { x: 0, y: 0, width: 640, height: 480}, min_size: { x: 0, y: 0, width: 640, height: 480}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 8, fourcc: FOURCC('Y','8','0','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 640*480 }, { identifier: "Y(Mono16) 640x480", size: { x: 0, y: 0, width: 640, height: 480}, min_size: { x: 0, y: 0, width: 640, height: 480}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('Y','1','6','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 640*480*2 }, { identifier: "Reserved", size: { x: 0, y: 0, width: 0, height: 0}, min_size: { x: 0, y: 0, width: 0, height: 0}, max_size: { x: 0, y: 0, width: 0, height: 0}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 0, fourcc: FOURCC('R','S','V','D'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 0 }, // format1 { identifier: "YUV(4:2:2) 800x600", size: { x: 0, y: 0, width: 800, height: 600}, min_size: { x: 0, y: 0, width: 800, height: 600}, max_size: { x: 0, y: 0, width: 800, height: 600}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('U','Y','V','Y'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 800*600*2 }, { identifier: "RGB 800x600", size: { x: 0, y: 0, width: 800, height: 600}, min_size: { x: 0, y: 0, width: 800, height: 600}, max_size: { x: 0, y: 0, width: 800, height: 600}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 24, fourcc: FOURCC('R','G','B',' '), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 800*600*3 }, { identifier: "Y(Mono) 800x600", size: { x: 0, y: 0, width: 800, height: 600}, min_size: { x: 0, y: 0, width: 800, height: 600}, max_size: { x: 0, y: 0, width: 800, height: 600}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 8, fourcc: FOURCC('Y','8','0','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 800*600 }, { identifier: "YUV(4:2:2) 1024x768", size: { x: 0, y: 0, width: 1024, height: 768}, min_size: { x: 0, y: 0, width: 1024, height: 768}, max_size: { x: 0, y: 0, width: 1024, height: 768}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('U','Y','V','Y'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1024*768*2 }, { identifier: "RGB 1024x768", size: { x: 0, y: 0, width: 1024, height: 768}, min_size: { x: 0, y: 0, width: 1024, height: 768}, max_size: { x: 0, y: 0, width: 1024, height: 768}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 24, fourcc: FOURCC('R','G','B',' '), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1024*768*3 }, { identifier: "Y(Mono) 1024x768", size: { x: 0, y: 0, width: 1024, height: 768}, min_size: { x: 0, y: 0, width: 1024, height: 768}, max_size: { x: 0, y: 0, width: 1024, height: 768}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 8, fourcc: FOURCC('Y','8','0','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1024*768 }, { identifier: "Y(Mono16) 800x600", size: { x: 0, y: 0, width: 800, height: 600}, min_size: { x: 0, y: 0, width: 800, height: 600}, max_size: { x: 0, y: 0, width: 800, height: 600}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('Y','1','6','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 800*600*2 }, { identifier: "Y(Mono16) 1024x768", size: { x: 0, y: 0, width: 1024, height: 768}, min_size: { x: 0, y: 0, width: 1024, height: 768}, max_size: { x: 0, y: 0, width: 1024, height: 768}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('Y','1','6','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1024*768*2 }, //format2 { identifier: "YUV(4:2:2) 1280x960", size: { x: 0, y: 0, width: 1280, height: 960}, min_size: { x: 0, y: 0, width: 1280, height: 960}, max_size: { x: 0, y: 0, width: 1280, height: 960}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('U','Y','V','Y'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1280*960*2 }, { identifier: "RGB 1280x960", size: { x: 0, y: 0, width: 1280, height: 960}, min_size: { x: 0, y: 0, width: 1280, height: 960}, max_size: { x: 0, y: 0, width: 1280, height: 960}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 24, fourcc: FOURCC('R','G','B',' '), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1280*960*3 }, { identifier: "Y(Mono) 1280x960", size: { x: 0, y: 0, width: 1280, height: 960}, min_size: { x: 0, y: 0, width: 1280, height: 960}, max_size: { x: 0, y: 0, width: 1280, height: 960}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 8, fourcc: FOURCC('Y','8','0','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1280*960 }, { identifier: "YUV(4:2:2) 1600x1200", size: { x: 0, y: 0, width: 1600, height: 1200}, min_size: { x: 0, y: 0, width: 1600, height: 1200}, max_size: { x: 0, y: 0, width: 1600, height: 1200}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('U','Y','V','Y'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1600*1200*2 }, { identifier: "RGB 1600x1200", size: { x: 0, y: 0, width: 1600, height: 1200}, min_size: { x: 0, y: 0, width: 1600, height: 1200}, max_size: { x: 0, y: 0, width: 1600, height: 1200}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 24, fourcc: FOURCC('R','G','B',' '), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1600*1200*3 }, { identifier: "Y(Mono) 1600x1200", size: { x: 0, y: 0, width: 1600, height: 1200}, min_size: { x: 0, y: 0, width: 1600, height: 1200}, max_size: { x: 0, y: 0, width: 1600, height: 1200}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 8, fourcc: FOURCC('Y','8','0','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1600*1200 }, { identifier: "Y(Mono16) 1280x960" , size: { x: 0, y: 0, width: 1280, height: 960}, min_size: { x: 0, y: 0, width: 1280, height: 960}, max_size: { x: 0, y: 0, width: 1280, height: 960}, bpp: 16, fourcc: FOURCC('Y','1','6','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1280*960*2 }, { identifier: "Y(Mono16) 1600x1200", size: { x: 0, y: 0, width: 1600, height: 1200}, min_size: { x: 0, y: 0, width: 1600, height: 1200}, max_size: { x: 0, y: 0, width: 1600, height: 1200}, h_stepping: -1, v_stepping: -1, sizes: 0, size_count: 0, bpp: 16, fourcc: FOURCC('Y','1','6','0'), flags: 0, buffer_types: UNICAP_BUFFER_TYPE_USER | UNICAP_BUFFER_TYPE_SYSTEM, system_buffer_count: DCAM_NUM_DMA_BUFFERS, buffer_size: 1600*1200*2 } }; #endif//__DCAM_FORMAT_TABLE_H__ libunicap/cpi/dcam/dcam_property_table.h0000644000175000017500000010041313164711411021123 0ustar zmoelnigzmoelnig /* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_PROPERTY_TABLE_H__ #define __DCAM_PROPERTY_TABLE_H__ #include "unicap_cpi_std_struct.h" #include "dcam.h" #include "dcam_property.h" #define N_(x) x #define PPTY_FLAGS 0 #define PPTY_MASK 0xffffffffffffffffULL #define DCAM_CAT_VIDEO N_("Video") #define DCAM_CAT_EXPOSURE N_("Exposure") #define DCAM_CAT_LENS N_("Lens Control") #define DCAM_CAT_COLOR N_("Color") #define DCAM_CAT_DEVICE N_("Device") #define DCAM_UNIT_NONE "" #define DCAM_UNIT_US "us" static char *strobe_mode_menu[] = { N_("constant low"), N_("constant high"), N_("fixed duration"), N_("exposure") }; static char *strobe_polarity_menu[] = { N_("active low"), N_("active high") }; #define STROBE_MODE_DEFAULT_ITEM "exposure" char *dcam_brightness_relations[] = { "shutter", "gain", "gamma", "iris", }; char *dcam_auto_exposure_relations[]= { }; char *dcam_sharpness_relations[] = { }; char *dcam_white_balance_mode_relations[] = { "white_balance_u", "white_balance_v", }; char *dcam_white_balance_u_relations[] = { "white_balance_v", }; char *dcam_white_balance_v_relations[] = { "white_balance_u", }; char *dcam_hue_relations[] = { }; char *dcam_saturation_relations[] = { }; char *dcam_gamma_relations[] = { "brightness", }; char *dcam_shutter_relations[] = { "gain", "brightness", "gamma", "iris", }; char *dcam_gain_relations[] = { "shutter", "brightness", "gamma", "iris", }; char *dcam_iris_relations[] = { "shutter", "gain", "brightness", "gamma", }; char *dcam_focus_relations[] = { "zoom", }; char *dcam_temperature_relations[] = { }; char *dcam_trigger_mode_relations[] = { }; char *dcam_trigger_modes[]= { N_("free running"), N_("mode 0"), N_("mode 1"), N_("mode 2"), N_("mode 3"), }; static char *dcam_trigger_polarity[]= { N_("falling edge"), N_("rising edge") }; char *dcam_zoom_relations[] = { "focus", }; char *dcam_pan_relations[] = { "tilt", }; char *dcam_tilt_relations[] = { "pan", }; char *dcam_optical_filter_relations[] = { }; char *dcam_capture_quality_relations[] = { }; char *dcam_frame_rate_relations[] = { }; char *dcam_register_relations[] = { }; char *dcam_timeout_relations[] = { }; struct _dcam_property _dcam_properties[]= { { id: DCAM_PPTY_BRIGHTNESS, unicap_property: { identifier: N_("brightness"), category: DCAM_CAT_EXPOSURE, unit: DCAM_UNIT_NONE, relations: dcam_brightness_relations, relations_count: sizeof( dcam_brightness_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 1.0} }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x000, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, #if 0 { id: DCAM_PPTY_ABS_FOCUS, unicap_property: { identifier: "abs focus", category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: 0, relations_count: 0, { value: 300.0 }, { range: { min: 70.0, max: 620.0} }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0xfff970, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_rw_register_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, { id: DCAM_PPTY_ABS_ZOOM, unicap_property: { identifier: "abs zoom", category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: 0, relations_count: 0, { value: 300.0 }, { range: { min: 10.0, max: 350.0} }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0xfff974, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_rw_register_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, { id: DCAM_PPTY_INIT_LENS, unicap_property: { identifier: "init lens", category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: 0, relations_count: 0, { value: 0.0 }, { range: { min: 0.0, max: 1.0} }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0xfff998, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_rw_register_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, #endif { id: DCAM_PPTY_STROBE_MODE, unicap_property: { identifier: N_("strobe_mode"), category: DCAM_CAT_DEVICE, unit: DCAM_UNIT_NONE, relations: 0, relations_count: 0, { menu_item: {STROBE_MODE_DEFAULT_ITEM} }, { menu: { menu_items: strobe_mode_menu, menu_item_count: sizeof( strobe_mode_menu ) / sizeof( char* ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0x3c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_strobe_mode_property, get_function: dcam_get_strobe_mode_property, init_function: dcam_init_gpio_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, { id: DCAM_PPTY_STROBE_DURATION, unicap_property: { identifier: N_("strobe_duration"), category: DCAM_CAT_DEVICE, unit: DCAM_UNIT_US, relations: 0, relations_count: 0, { value: 10.0 }, { range: { min: 10.0, max: 40000.0 } }, stepping: 10.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x3c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_strobe_duration_property, get_function: dcam_get_strobe_duration_property, init_function: dcam_init_gpio_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, { id: DCAM_PPTY_STROBE_DELAY, unicap_property: { identifier: N_("strobe_delay"), category: DCAM_CAT_DEVICE, unit: DCAM_UNIT_US, relations: 0, relations_count: 0, { value: 0.0 }, { range: { min: -20000.0, max: 20000.0 } }, stepping: 10.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x3c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_strobe_delay_property, get_function: dcam_get_strobe_delay_property, init_function: dcam_init_gpio_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, { id: DCAM_PPTY_STROBE_POLARITY, unicap_property: { identifier: N_("strobe_polarity"), category: DCAM_CAT_DEVICE, unit: DCAM_UNIT_NONE, relations: 0, relations_count: 0, { menu_item: {STROBE_MODE_DEFAULT_ITEM} }, { menu: { menu_items: strobe_polarity_menu, menu_item_count: sizeof( strobe_polarity_menu ) / sizeof( char* ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0x3c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_strobe_polarity_property, get_function: dcam_get_strobe_polarity_property, init_function: dcam_init_gpio_property, feature_hi_mask: 1<<31, feature_lo_mask: 0, }, { id: DCAM_PPTY_AUTO_EXPOSURE, unicap_property: { identifier: N_("auto_exposure"), category: DCAM_CAT_EXPOSURE, unit: DCAM_UNIT_NONE, relations: dcam_auto_exposure_relations, relations_count: sizeof( dcam_auto_exposure_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 1.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x004, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<30, feature_lo_mask: 0, }, { id: DCAM_PPTY_SHARPNESS, unicap_property: { identifier: N_("sharpness"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_sharpness_relations, relations_count: sizeof( dcam_sharpness_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: -1.0, max: 1.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x008, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<29, feature_lo_mask: 0, }, { id: DCAM_PPTY_WHITE_BALANCE_MODE, unicap_property: { identifier: N_("white_balance_mode"), category: DCAM_CAT_COLOR, unit: DCAM_UNIT_NONE, relations: dcam_white_balance_mode_relations, relations_count: sizeof( dcam_white_balance_mode_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x00c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_WHITEBAL_U, set_function: dcam_set_white_balance_mode_property, get_function: dcam_get_white_balance_mode_property, init_function: dcam_init_white_balance_mode_property, feature_hi_mask: 1<<28, feature_lo_mask: 0, }, { id: DCAM_PPTY_WHITE_BALANCE_U, unicap_property: { identifier: N_("white_balance_u"), category: DCAM_CAT_COLOR, unit: DCAM_UNIT_NONE, relations: dcam_white_balance_u_relations, relations_count: sizeof( dcam_white_balance_u_relations ) / sizeof( char * ), { value: 0.5 }, { range: { min: 0.0, max: 1.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x00c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_WHITEBAL_U, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_white_balance_property, feature_hi_mask: 1<<28, feature_lo_mask: 0, }, { id: DCAM_PPTY_WHITE_BALANCE_V, unicap_property: { identifier: N_("white_balance_v"), category: DCAM_CAT_COLOR, unit: DCAM_UNIT_NONE, relations: dcam_white_balance_v_relations, relations_count: sizeof( dcam_white_balance_v_relations ) / sizeof( char * ), { value: 0.5 }, { range: { min: 0.0, max: 1.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x00c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_WHITEBAL_V, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_white_balance_property, feature_hi_mask: 1<<28, feature_lo_mask: 0, }, { id: DCAM_PPTY_HUE, unicap_property: { identifier: N_("hue"), category: DCAM_CAT_COLOR, unit: DCAM_UNIT_NONE, relations: dcam_hue_relations, relations_count: sizeof( dcam_hue_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: -1.0, max: 1.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x010, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<27, feature_lo_mask: 0, }, { id: DCAM_PPTY_SATURATION, unicap_property: { identifier: N_("saturation"), category: DCAM_CAT_COLOR, unit: DCAM_UNIT_NONE, relations: dcam_saturation_relations, relations_count: sizeof( dcam_saturation_relations ) / sizeof( char * ), { value: 0.5 }, { range: { min: 0.0, max: 1.0 } }, stepping: 0.01, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x014, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<26, feature_lo_mask: 0, }, { id: DCAM_PPTY_GAMMA, unicap_property: { identifier: N_("gamma"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_gamma_relations, relations_count: sizeof( dcam_gamma_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x018, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<25, feature_lo_mask: 0, }, { id: DCAM_PPTY_SHUTTER, unicap_property: { identifier: N_("shutter"), category: DCAM_CAT_EXPOSURE, unit: DCAM_UNIT_NONE, relations: dcam_shutter_relations, relations_count: sizeof( dcam_shutter_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x01c, absolute_offset: 0, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_shutter_property, feature_hi_mask: 1<<24, feature_lo_mask: 0, }, { id: DCAM_PPTY_GAIN, unicap_property: { identifier: N_("gain"), category: DCAM_CAT_EXPOSURE, unit: DCAM_UNIT_NONE, relations: dcam_gain_relations, relations_count: sizeof( dcam_gain_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x020, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<23, feature_lo_mask: 0, }, { id: DCAM_PPTY_IRIS, unicap_property: { identifier: N_("iris"), category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: dcam_iris_relations, relations_count: sizeof( dcam_iris_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x024, register_inq: 0, register_default: 0, register_value: 0, PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<22, feature_lo_mask: 0, }, { id: DCAM_PPTY_FOCUS, unicap_property: { identifier: N_("focus"), category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: dcam_focus_relations, relations_count: sizeof( dcam_focus_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x028, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<21, feature_lo_mask: 0, }, { id: DCAM_PPTY_TEMPERATURE, unicap_property: { identifier: N_("temperature"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_temperature_relations, relations_count: sizeof( dcam_temperature_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x02c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_TEMPERATURE, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 1<<20, feature_lo_mask: 0, }, #if 0 { id: DCAM_PPTY_SOFTWARE_TRIGGER, unicap_property: { identifier: N_("software trigger"), category: DCAM_CAT_DEVICE, relations: NULL, relations_count: 0, { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH, flags_mask: UNICAP_FLAGS_ONE_PUSH, property_data: NULL, property_data_size: 0 }, register_offset: 0x54, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_REGISTER, set_function: dcam_set_software_trigger_property, get_function: dcam_get_software_trigger_property, init_function: dcam_init_software_trigger_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, #endif { id: DCAM_PPTY_TRIGGER_MODE, unicap_property: { identifier: N_("trigger_mode"), category: DCAM_CAT_DEVICE, unit: DCAM_UNIT_NONE, relations: dcam_trigger_mode_relations, relations_count: sizeof( dcam_trigger_mode_relations ) / sizeof( char * ), { value: 0.0 }, { value_list: { values: NULL, value_count: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0x030, 0, 0, 0, type: PPTY_TYPE_TRIGGER, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_trigger_property, feature_hi_mask: 1<<19, feature_lo_mask: 0, }, { id: DCAM_PPTY_TRIGGER_POLARITY, unicap_property: { identifier: N_("trigger_polarity"), category: DCAM_CAT_DEVICE, unit: DCAM_UNIT_NONE, relations: dcam_trigger_mode_relations, relations_count: sizeof( dcam_trigger_mode_relations ) / sizeof( char * ), { value: 0.0 }, { value_list: { values: NULL, value_count: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0x030, 0, 0, 0, type: PPTY_TYPE_TRIGGER_POLARITY, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_trigger_property, feature_hi_mask: 1<<19, feature_lo_mask: 0, }, { id: DCAM_PPTY_ZOOM, unicap_property: { identifier: N_("zoom"), category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: dcam_zoom_relations, relations_count: sizeof( dcam_zoom_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x080, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 0, feature_lo_mask: 1<<31, }, { id: DCAM_PPTY_PAN, unicap_property: { identifier: /* TRANSLATORS: Lens pan */ N_("pan"), category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: dcam_pan_relations, relations_count: sizeof( dcam_pan_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x084, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 0, feature_lo_mask: 1<<30, }, { id: DCAM_PPTY_TILT, unicap_property: { identifier: /* TRANSLATORS: Lens tilt */ N_("tilt"), category: DCAM_CAT_LENS, unit: DCAM_UNIT_NONE, relations: dcam_tilt_relations, relations_count: sizeof( dcam_tilt_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x088, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 0, feature_lo_mask: 1<<29, }, { id: DCAM_PPTY_OPTICAL_FILTER, unicap_property: { identifier: N_("optical_filter"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_optical_filter_relations, relations_count: sizeof( dcam_optical_filter_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x08c, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 0, feature_lo_mask: 1<<28, }, { id: DCAM_PPTY_CAPTURE_QUALITY, unicap_property: { identifier: N_("capture_quality"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_capture_quality_relations, relations_count: sizeof( dcam_capture_quality_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: PPTY_MASK, property_data: NULL, property_data_size: 0 }, register_offset: 0x0c4, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_BRIGHTNESS, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_brightness_property, feature_hi_mask: 0, feature_lo_mask: 1<<15, }, { id: DCAM_PPTY_FRAME_RATE, unicap_property: { identifier: N_("frame rate"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_frame_rate_relations, relations_count: sizeof( dcam_frame_rate_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_VALUE_LIST, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_FRAMERATE, set_function: dcam_set_frame_rate_property, get_function: dcam_get_frame_rate_property, init_function: dcam_init_frame_rate_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, { id: DCAM_PPTY_RW_REGISTER, unicap_property: { identifier: /* TRANSLATORS: Camera hardware register */ N_("register"), category: DCAM_CAT_VIDEO, unit: DCAM_UNIT_NONE, relations: dcam_register_relations, relations_count: sizeof( dcam_register_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_REGISTER, set_function: dcam_set_property, get_function: dcam_get_property, init_function: dcam_init_rw_register_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, { id: DCAM_PPTY_TIMEOUT, unicap_property: { identifier: N_("timeout"), category: DCAM_CAT_DEVICE, relations: dcam_timeout_relations, relations_count: sizeof( dcam_timeout_relations ) / sizeof( char * ), { value: 1.0 }, { range: { min: 0.0, max: 600.0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_REGISTER, set_function: dcam_set_timeout_property, get_function: dcam_get_timeout_property, init_function: dcam_init_timeout_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, { id: DCAM_PPTY_GPIO, unicap_property: { identifier: N_("gpio"), category: DCAM_CAT_DEVICE, relations: dcam_timeout_relations, relations_count: sizeof( dcam_timeout_relations ) / sizeof( char * ), { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_DATA, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0x38, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_REGISTER, set_function: dcam_set_gpio_property, get_function: dcam_get_gpio_property, init_function: dcam_init_gpio_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, { id: DCAM_PPTY_ENABLE_FRAME_DROP, unicap_property: { identifier: N_("enable frame drop"), category: DCAM_CAT_DEVICE, relations: NULL, relations_count: 0, { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF, property_data: NULL, property_data_size: 0 }, register_offset: 0, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_REGISTER, set_function: dcam_set_enable_frame_drop_property, get_function: dcam_get_enable_frame_drop_property, init_function: dcam_init_enable_frame_drop_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, { id: DCAM_PPTY_FRAME_DROP_COUNT, unicap_property: { identifier: N_("frame drop count"), category: DCAM_CAT_DEVICE, relations: NULL, relations_count: 0, { value: 0.0 }, { range: { min: 0.0, max: 0.0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 }, register_offset: 0, register_inq: 0, register_default: 0, register_value: 0, type: PPTY_TYPE_REGISTER, set_function: dcam_set_frame_drop_property, get_function: dcam_get_frame_drop_property, init_function: dcam_init_frame_drop_property, feature_hi_mask: 0xffffffff, feature_lo_mask: 0xffffffff, }, { id: DCAM_PPTY_END } }; #endif//__DCAM_PROPERTY_TABLE_H__ libunicap/cpi/dcam/dcam_busreset.h0000644000175000017500000000166413164711411017734 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_BUSRESET_H__ #define __DCAM_BUSRESET_H__ int dcam_busreset_handler( raw1394handle_t raw1394handle, unsigned int generation ); #endif//__DCAM_BUSRESET_H__ libunicap/cpi/dcam/dcam_property.c0000644000175000017500000013454213164711411017761 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif #include #include #include #include #include "dcam.h" #include "dcam_functions.h" #include "dcam_property_table.h" #include "dcam_v_modes.h" #include "dcam_defs.h" #include "1394util.h" #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" struct _dcam_raw_register { nodeaddr_t address; quadlet_t value; }; typedef struct _dcam_raw_register dcam_raw_register_t; /* returns 1 if the given property is enabled in either feature_hi or feature_lo */ int _dcam_check_property_supported( quadlet_t feature_hi, quadlet_t feature_lo, dcam_property_t *property ) { int supported = 0; switch( property->register_offset ) { case 0: supported = (feature_hi>>31)&1; //.brightness; break; case 0x4: supported = (feature_hi>>30)&1; //.auto_exposure; break; case 0x8: supported = (feature_hi>>29)&1; //.sharpness; break; case 0xc: supported = (feature_hi>>28)&1; //.white_balance; break; case 0x10: supported = (feature_hi>>27)&1; //.hue; break; case 0x14: supported = (feature_hi>>26)&1; //.saturation; break; case 0x18: supported = (feature_hi>>25)&1; //.gamma; break; case 0x1c: supported = (feature_hi>>24)&1; //.shutter; break; case 0x20: supported = (feature_hi>>23)&1; //.gain; break; case 0x24: supported = (feature_hi>>22)&1; //.iris; break; case 0x28: supported = (feature_hi>>21)&1; //.focus; break; case 0x2c: supported = (feature_hi>>20)&1; //.temperature; break; case 0x30: supported = (feature_hi>>19)&1; //.trigger; break; case 0x80: supported = (feature_lo>>31)&1; //.zoom; break; case 0x84: supported = (feature_lo>>30)&1; //.pan; break; case 0x88: supported = (feature_lo>>29)&1; //.tilt; break; case 0x8c: supported = (feature_lo>>28)&1; //.optical_filter; break; case 0xc0: supported = (feature_lo>>16)&1; //.capture_size; break; case 0xc4: supported = (feature_lo>>15)&1; //.capture_quality; break; default: supported = 0; break; } return supported; } unicap_status_t dcam_init_property_std_flags( dcam_handle_t dcamhandle, dcam_property_t *dcam_property ) { quadlet_t val = dcam_property->register_inq; dcam_property->unicap_property.flags_mask = 0; if( GETFLAG_ON_OFF_INQ( val ) ) // ON_OFF inq { dcam_property->unicap_property.flags_mask |= UNICAP_FLAGS_ON_OFF; } if( GETFLAG_AUTO_INQ( val ) && // AUTO inq (dcam_property->type != PPTY_TYPE_TRIGGER ) && (dcam_property->type != PPTY_TYPE_TRIGGER_POLARITY )) { dcam_property->unicap_property.flags_mask |= UNICAP_FLAGS_AUTO; } if( GETFLAG_MANUAL_INQ( val ) && // MANUAL inq (dcam_property->type != PPTY_TYPE_TRIGGER ) && (dcam_property->type != PPTY_TYPE_TRIGGER_POLARITY ) ) { dcam_property->unicap_property.flags_mask |= UNICAP_FLAGS_MANUAL; } if( GETFLAG_ONE_PUSH_INQ( val ) && // ONE_PUSH inq (dcam_property->type != PPTY_TYPE_TRIGGER ) && (dcam_property->type != PPTY_TYPE_TRIGGER_POLARITY ) ) { dcam_property->unicap_property.flags_mask |= UNICAP_FLAGS_ONE_PUSH; } return STATUS_SUCCESS; } unicap_status_t dcam_read_default_and_inquiry( dcam_handle_t dcamhandle, dcam_property_t *dcam_property ) { quadlet_t val; quadlet_t default_val; // read inquiry register for this ppty if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x500 + dcam_property->register_offset, &val ) < 0 ) { dcam_property->register_inq = 0; return STATUS_FAILURE; } dcam_property->register_inq = val; TRACE( "Inquiry[%x]: %08x\n", dcam_property->register_offset, dcam_property->register_inq ); // // only consider properties if: // - the property inquiry register has presence flag set if( GETFLAG_PRESENCE_INQ( val ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, &default_val ) < 0 ) { dcam_property->register_inq = 0; return STATUS_FAILURE; } if( !GETFLAG_PRESENCE_INQ( default_val ) ) { TRACE( "dcam: property_inq reports presence but property_cntl does not! disabling property\n" ); dcam_property->register_inq = 0; return STATUS_NOT_IMPLEMENTED; } dcam_property->register_default = default_val; dcam_property->register_value = default_val; } else { return STATUS_NOT_IMPLEMENTED; } return STATUS_SUCCESS; } unicap_status_t dcam_init_gpio_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { if( dcamhandle->unicap_device.vendor_id != 0x748 ) { return STATUS_NOT_IMPLEMENTED; } if( ( ( dcamhandle->unicap_device.model_id >> 32 ) & 0xff ) != 0x12 ) { return STATUS_NOT_IMPLEMENTED; } return STATUS_SUCCESS; } unicap_status_t dcam_set_gpio_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; unicap_status_t status; if( property->property_data_size < ( sizeof( unsigned int ) ) ) { return STATUS_INVALID_PARAMETER; } quad = *(quadlet_t *)property->property_data; status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, quad ); return status; } unicap_status_t dcam_get_gpio_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; unicap_status_t status; if( property->property_data_size < ( sizeof( unsigned int ) ) ) { return STATUS_INVALID_PARAMETER; } status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); *(quadlet_t *)property->property_data = quad; return status; } unicap_status_t dcam_init_software_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { if( dcamhandle->unicap_device.vendor_id != 0x748 ) { return STATUS_NOT_IMPLEMENTED; } if( ( ( dcamhandle->unicap_device.model_id >> 32 ) & 0xff ) != 0x12 ) { return STATUS_NOT_IMPLEMENTED; } return STATUS_SUCCESS; } unicap_status_t dcam_set_software_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad = 0; unicap_status_t status; if( property->flags & UNICAP_FLAGS_ONE_PUSH ) { quad = SETFLAG_ONE_PUSH( quad, 1 ); } else { quad = SETFLAG_ONE_PUSH( quad, 0 ); } status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, quad ); return status; } unicap_status_t dcam_get_software_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { property->flags = UNICAP_FLAGS_MANUAL; return STATUS_SUCCESS; } unicap_status_t dcam_set_strobe_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; unicap_status_t status = STATUS_SUCCESS; quad = 0; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); quad = SETFLAG_PRESENCE( quad, 1 ); quad = SETFLAG_ON_OFF( quad, 1 ); if( !strcmp( property->menu_item, "constant low" ) ) { quad = SETFLAG_ONE_PUSH( quad, 0 ); // polarity 0 quad = SETVAL_V_VALUE( quad, 0 ); // duration 0 quad = SETVAL_U_VALUE( quad, 0 ); // delay 0 quad = SETFLAG_AUTO( quad, 0 ); // mode 0 = fixed duration } else if( !strcmp( property->menu_item, "constant high" ) ) { quad = SETFLAG_ONE_PUSH( quad, 1 ); // polarity 1 quad = SETVAL_V_VALUE( quad, 0 ); // duration 0 quad = SETVAL_U_VALUE( quad, 0 ); // delay 0 quad = SETFLAG_AUTO( quad, 0 ); // mode 0 = fixed duration } else if( !strcmp( property->menu_item, "fixed duration" ) ) { quad = SETFLAG_AUTO( quad, 0 ); // mode 0 = fixed duration quad = SETVAL_V_VALUE( quad, 1 ); } else if( !strcmp( property->menu_item, "exposure" ) ) { quad = SETFLAG_AUTO( quad, 1 ); // mode 1 = strobe follows exposure } else { status = STATUS_INVALID_PARAMETER; TRACE( "unknown strobe mode\n" ); } if( SUCCESS( status ) ) { status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, quad ); } return status; } unicap_status_t dcam_get_strobe_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status; quadlet_t quad; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); if( GETFLAG_AUTO( quad ) ) { // mode = 1 --> strobe follows exposure strcpy( property->menu_item, dcam_property->unicap_property.menu.menu_items[3] ); } else if( GETVAL_V_VALUE( quad ) == 0 ) { if( GETFLAG_ONE_PUSH( quad ) ) { // polarity = 1 --> constant high strcpy( property->menu_item, dcam_property->unicap_property.menu.menu_items[1] ); } else { // polarity == 0 -> constant lo strcpy( property->menu_item, dcam_property->unicap_property.menu.menu_items[0] ); } } else { strcpy( property->menu_item, dcam_property->unicap_property.menu.menu_items[2] ); } return status; } unicap_status_t dcam_set_strobe_duration_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; unicap_status_t status; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); quad = SETFLAG_ON_OFF( quad, 1 ); quad = SETVAL_V_VALUE( quad, (int) ( property->value / 10.0 ) ); if( SUCCESS( status ) ) { status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, quad ); } return status; } unicap_status_t dcam_get_strobe_duration_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; double value; unicap_status_t status; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); value = GETVAL_V_VALUE( quad ); property->value = value * 10.0; property->flags_mask = UNICAP_FLAGS_MANUAL; if( GETVAL_V_VALUE(quad) == 0 ) { property->flags = UNICAP_FLAGS_READ_ONLY; } else { property->flags = UNICAP_FLAGS_MANUAL; } return status; } unicap_status_t dcam_set_strobe_delay_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; unicap_status_t status; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); quad = SETFLAG_ON_OFF( quad, 1 ); quad = SETVAL_U_VALUE( quad, (int) ( property->value / 10.0 ) ); if( SUCCESS( status ) ) { status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, quad ); } return status; } unicap_status_t dcam_get_strobe_delay_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; double value; unicap_status_t status; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); value = GETVAL_U_VALUE( quad ); property->value = value * 10.0; property->flags_mask = UNICAP_FLAGS_MANUAL; if( GETVAL_V_VALUE(quad) == 0 ) { property->flags = UNICAP_FLAGS_READ_ONLY; } else { property->flags = UNICAP_FLAGS_MANUAL; } return status; } unicap_status_t dcam_set_strobe_polarity_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t quad; unicap_status_t status = STATUS_SUCCESS; quad = 0; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); quad = SETFLAG_PRESENCE( quad, 1 ); quad = SETFLAG_ON_OFF( quad, 1 ); if( !strcmp( property->menu_item, "active low" ) ) { quad = SETFLAG_ONE_PUSH( quad, 0 ); // polarity 0 } else if( !strcmp( property->menu_item, "active high" ) ) { quad = SETFLAG_ONE_PUSH( quad, 1 ); // polarity 1 } else { status = STATUS_INVALID_PARAMETER; TRACE( "unknown strobe mode\n" ); } if( SUCCESS( status ) ) { status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, quad ); } return status; } unicap_status_t dcam_get_strobe_polarity_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status; quadlet_t quad; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x1000000 + dcam_property->register_offset, &quad ); if( GETFLAG_ONE_PUSH( quad ) ) { // polarity = 1 strcpy( property->menu_item, dcam_property->unicap_property.menu.menu_items[1] ); } else { // polarity == 0 -> constant lo strcpy( property->menu_item, dcam_property->unicap_property.menu.menu_items[0] ); } property->flags_mask = UNICAP_FLAGS_MANUAL; if( GETVAL_V_VALUE(quad) == 0 ) { property->flags = UNICAP_FLAGS_READ_ONLY; } else { property->flags = UNICAP_FLAGS_MANUAL; } return status; } unicap_status_t dcam_init_timeout_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { dcamhandle->timeout_seconds = 1.0; return STATUS_SUCCESS; } unicap_status_t dcam_get_timeout_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_copy_property( property, &dcam_property->unicap_property ); property->value = dcamhandle->timeout_seconds; return STATUS_SUCCESS; } unicap_status_t dcam_set_timeout_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; if( ( property->value >= dcam_property->unicap_property.range.min ) && ( property->value <= dcam_property->unicap_property.range.max ) ) { dcamhandle->timeout_seconds = property->value; } else { status = STATUS_INVALID_PARAMETER; } return status; } unicap_status_t dcam_init_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { dcamhandle->frame_drop_count = 0; return STATUS_SUCCESS; } unicap_status_t dcam_get_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_copy_property( property, &dcam_property->unicap_property ); property->value = dcamhandle->frame_drop_count; return STATUS_SUCCESS; } unicap_status_t dcam_set_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; dcamhandle->frame_drop_count = property->value; return status; } unicap_status_t dcam_init_enable_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { dcamhandle->enable_frame_drop = 0; return STATUS_SUCCESS; } unicap_status_t dcam_get_enable_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_copy_property( property, &dcam_property->unicap_property ); if (dcamhandle->enable_frame_drop) property->flags = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF; else property->flags = UNICAP_FLAGS_MANUAL; return STATUS_SUCCESS; } unicap_status_t dcam_set_enable_frame_drop_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; if (property->flags & UNICAP_FLAGS_ON_OFF) dcamhandle->enable_frame_drop = 1; else dcamhandle->enable_frame_drop = 0; return status; } static unicap_status_t dcam_set_shutter_abs( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; abs_value_t value; quadlet_t quad = 0; quad = SETFLAG_PRESENCE( quad, 1 ); if( property->flags & UNICAP_FLAGS_AUTO ) { quad = SETFLAG_AUTO( quad, 1 ); } else { quad = SETFLAG_ABS_CONTROL( quad, 1 ); } quad = SETFLAG_ON_OFF( quad, 1 ); if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, quad ) < 0 ) { TRACE( "failed to write shutter setting\n" ); status = STATUS_FAILURE; } if( SUCCESS( status ) ) { value.f = property->value; if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, CSR_REGISTER_BASE + dcam_property->absolute_offset + 8, value.quad ) < 0 ) { status = STATUS_FAILURE; } } return status; } static unicap_status_t dcam_get_shutter_abs( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; float value; quadlet_t quad; if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, &quad ) < 0 ) { TRACE( "failed to read shutter setting\n" ); status = STATUS_FAILURE; } if( GETFLAG_AUTO( quad ) ) { property->flags = UNICAP_FLAGS_AUTO; } else { property->flags = UNICAP_FLAGS_MANUAL; } if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, CSR_REGISTER_BASE + dcam_property->absolute_offset + 8, (quadlet_t *)&value ) < 0 ) { status = STATUS_FAILURE; } else { property->value = value; } return status; } unicap_status_t dcam_init_shutter_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_FAILURE; status = dcam_read_default_and_inquiry( dcamhandle, dcam_property ); status = dcam_init_property_std_flags( dcamhandle, dcam_property ); if( SUCCESS( status ) ) { if( GETFLAG_ABS_CONTROL_INQ( dcam_property->register_inq ) ) { quadlet_t abs_offset; float min; float max; float def; quadlet_t quad; // read inquiry register for this ppty if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x700 + dcam_property->register_offset, &abs_offset ) < 0 ) { TRACE( "failed to read abs offset\n" ); status = STATUS_FAILURE; } abs_offset *= 4; dcam_property->absolute_offset = abs_offset; TRACE( "abs_offset: %x\n", abs_offset ); if( SUCCESS( status ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, CSR_REGISTER_BASE + abs_offset, (quadlet_t *)&min ) < 0 ) { TRACE( "failed to read abs min : %llx\n", dcamhandle->command_regs_base ); status = STATUS_FAILURE; } else { dcam_property->unicap_property.range.min = min; TRACE( "abs shutter min: %f\n", min ); } } if( SUCCESS( status ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, CSR_REGISTER_BASE + abs_offset + 4, (quadlet_t *)&max ) < 0 ) { TRACE( "failed to read abs max\n" ); status = STATUS_FAILURE; } else { dcam_property->unicap_property.range.max = max; TRACE( "abs shutter max: %f\n", max ); } } if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, &quad ) < 0 ) { TRACE( "failed to read shutter setting\n" ); status = STATUS_FAILURE; } if( SUCCESS( status ) ) { quad = SETFLAG_ABS_CONTROL( quad, 1 ); if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, quad ) < 0 ) { TRACE( "failed to write shutter setting\n" ); status = STATUS_FAILURE; } } if( SUCCESS( status ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, CSR_REGISTER_BASE + abs_offset + 8, (quadlet_t *)&def ) < 0 ) { TRACE( "failed to read abs value\n" ); status = STATUS_FAILURE; } else { dcam_property->unicap_property.value = def; } } if( SUCCESS( status ) ) { dcam_property->unicap_property.stepping = 0.005; dcam_property->set_function = dcam_set_shutter_abs; dcam_property->get_function = dcam_get_shutter_abs; strcpy( dcam_property->unicap_property.unit, "s" ); } } else { TRACE( "Abs shutter not supported\n" ); status = STATUS_FAILURE; } } if( !SUCCESS( status ) ) { status = dcam_init_brightness_property( dcamhandle, p, dcam_property ); } return status; } unicap_status_t dcam_init_brightness_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { unicap_status_t status; status = dcam_read_default_and_inquiry( dcamhandle, dcam_property ); if( SUCCESS( status ) ) { status = dcam_init_property_std_flags( dcamhandle, dcam_property ); dcam_property->unicap_property.value = GETVAL_VALUE( dcam_property->register_default ); dcam_property->unicap_property.range.min = GETVAL_MIN_VALUE( dcam_property->register_inq ); dcam_property->unicap_property.range.max = GETVAL_MAX_VALUE( dcam_property->register_inq ); dcam_property->unicap_property.stepping = 1.0f; } return status; } unicap_status_t dcam_init_white_balance_mode_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { unicap_status_t status; status = dcam_read_default_and_inquiry( dcamhandle, dcam_property ); if( SUCCESS( status ) ) { status = dcam_init_property_std_flags( dcamhandle, dcam_property ); } return status; } unicap_status_t dcam_init_white_balance_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { unicap_status_t status; status = dcam_read_default_and_inquiry( dcamhandle, dcam_property ); if( SUCCESS( status ) ) { // FLAGS are handled via "white_balance_mode" property dcam_property->unicap_property.flags = 0; dcam_property->unicap_property.flags_mask = UNICAP_FLAGS_MANUAL; if( dcam_property->type == PPTY_TYPE_WHITEBAL_U ) { dcam_property->unicap_property.value = GETVAL_U_VALUE( dcam_property->register_default ); } else { dcam_property->unicap_property.value = GETVAL_V_VALUE( dcam_property->register_default ); } dcam_property->unicap_property.range.min = GETVAL_MIN_VALUE( dcam_property->register_inq ); dcam_property->unicap_property.range.max = GETVAL_MAX_VALUE( dcam_property->register_inq ); dcam_property->unicap_property.stepping = 1.0f; } return status; } unicap_status_t dcam_init_trigger_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { unicap_status_t status; int trigger_mode_count = 1; dcamhandle->trigger_modes[0] = dcam_trigger_modes[0]; dcamhandle->trigger_modes[1] = dcam_trigger_modes[1]; dcamhandle->trigger_polarities[0] = dcam_trigger_polarity[0]; dcamhandle->trigger_polarities[1] = dcam_trigger_polarity[1]; status = dcam_read_default_and_inquiry( dcamhandle, dcam_property ); if( SUCCESS( status ) ) { status = dcam_init_property_std_flags( dcamhandle, dcam_property ); if( dcam_property->id == DCAM_PPTY_TRIGGER_MODE ) { if( ( ( dcam_property->register_inq >> 15 ) & 1 ) ) // trigger mode 0 { dcamhandle->trigger_modes[trigger_mode_count++] = dcam_trigger_modes[1]; } if( ( ( dcam_property->register_inq >> 16 ) & 1 ) ) // trigger mode 1 { dcamhandle->trigger_modes[trigger_mode_count++] = dcam_trigger_modes[2]; } if( ( ( dcam_property->register_inq >> 17 ) & 1 ) ) // trigger mode 2 { dcamhandle->trigger_modes[trigger_mode_count++] = dcam_trigger_modes[3]; } if( ( ( dcam_property->register_inq >> 18 ) & 1 ) ) // trigger mode 3 { dcamhandle->trigger_modes[trigger_mode_count++] = dcam_trigger_modes[4]; } dcam_property->unicap_property.menu.menu_items = dcamhandle->trigger_modes; dcam_property->unicap_property.menu.menu_item_count = trigger_mode_count; dcamhandle->trigger_mode_count = trigger_mode_count; /* dcam_property->unicap_property.value = ( dcam_property->register_default >> 16 ) & 0xf; */ if( ( ( dcam_property->register_default >> 16 ) & 0xf ) < trigger_mode_count ) { strcpy( dcam_property->unicap_property.menu_item, dcam_trigger_modes[ ( dcam_property->register_default>>16 ) & 0xf ] ); } else { TRACE( "Trigger default value out of range\n" ); } dcam_property->unicap_property.property_data_size = 4; dcam_property->unicap_property.property_data = ( &dcamhandle->trigger_parameter ); dcamhandle->trigger_parameter = ( dcam_property->register_default & 0xfff); dcam_property->unicap_property.flags_mask = UNICAP_FLAGS_MANUAL; } else { // TRIGGER_POLARITY if( ( dcam_property->register_inq >> 26 ) & 0x1 ) { int i; strcpy( dcam_property->unicap_property.menu_item, dcamhandle->trigger_polarities[( dcam_property->register_default >> 26 ) & 1] ); dcam_property->unicap_property.menu.menu_item_count = 2; dcam_property->unicap_property.menu.menu_items = dcamhandle->trigger_polarities; dcam_property->unicap_property.flags_mask = UNICAP_FLAGS_MANUAL; } else { status = STATUS_FAILURE; } } } return status; } unicap_status_t dcam_init_frame_rate_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { quadlet_t quad; quad = _dcam_get_supported_frame_rates( dcamhandle ); if( dcam_property->unicap_property.value_list.value_count > 0 ) { free( dcam_property->unicap_property.value_list.values ); } // 8 == max frame rates supported in DCAM 1.3 dcam_property->unicap_property.value_list.values = malloc( sizeof( double ) * 8 ); dcam_property->unicap_property.value_list.value_count = 0; if( quad ) { if( ( quad >> 31 ) &1 ) { dcam_property->unicap_property.value_list.values[dcam_property->unicap_property.value_list.value_count++] = 1.875; } if( ( quad >> 30 ) &1 ) { dcam_property->unicap_property.value_list.values[dcam_property->unicap_property.value_list.value_count++] = 3.75; } if( ( quad >> 29 ) &1 ) { dcam_property->unicap_property.value_list.values[dcam_property->unicap_property.value_list.value_count++] = 7.5; } if( ( quad >> 28 ) &1 ) { dcam_property->unicap_property.value_list.values[dcam_property->unicap_property.value_list.value_count++] = 15; } if( ( quad >> 27 ) &1 ) { dcam_property->unicap_property.value_list.values[dcam_property->unicap_property.value_list.value_count++] = 30; } if( ( quad >> 26 ) & 1 ) { dcam_property->unicap_property.value_list.values[dcam_property->unicap_property.value_list.value_count++] = 60; } } dcam_property->unicap_property.flags_mask = UNICAP_FLAGS_MANUAL; TRACE( "count: %d\n", dcam_property->unicap_property.value_list.value_count ); return STATUS_SUCCESS; } unicap_status_t dcam_init_rw_register_property( dcam_handle_t dcamhandle, unicap_property_t *p, dcam_property_t *dcam_property ) { return STATUS_SUCCESS; } /* fill property_table with properties supported by this camera. set _property_count to the number of entries entered into the table input: property_table: pointer to an allocated memory area _property_count: number of dcam_properties which are allocated in property_table */ unicap_status_t _dcam_prepare_property_table( dcam_handle_t dcamhandle, dcam_property_t **new_table ) { quadlet_t feature_hi, feature_lo; dcam_property_t *property_table; int i; _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x404, &feature_hi ); _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x408, &feature_lo ); TRACE( "feature hi:\n brightness: %d\n auto_exp: %d\n sharpness: %d\n whitebal: %d\n hue: %d\n" \ " saturation: %d\n gamma: %d\n shutter: %d\n iris: %d\n focus: %d\n temperature: %d\n trigger: %d\n", (feature_hi>>31)&1, (feature_hi>>30)&1, (feature_hi>>29)&1, (feature_hi>>27)&1, (feature_hi>>26)&1, (feature_hi>>25)&1, (feature_hi>>24)&1, (feature_hi>>23)&1, (feature_hi>>22)&1, (feature_hi>>21)&1, (feature_hi>>20)&1, (feature_hi>>19)&1 ); property_table = malloc( sizeof( _dcam_properties ) ); for( i = 0; i < ( sizeof( _dcam_properties ) / sizeof( struct _dcam_property ) ); i++ ) { dcam_copy_property( &property_table[i], &_dcam_properties[i] ); } *new_table = property_table; return STATUS_SUCCESS; } unicap_status_t dcam_set_frame_rate_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; quadlet_t quad = 0; if( property->value <= 1.875 ) { quad = SETVAL_FRAME_RATE( quad, 0 ); } else if( property->value <= 3.75 ) { quad = SETVAL_FRAME_RATE( quad, 1 ); } else if( property->value <= 7.5 ) { quad = SETVAL_FRAME_RATE( quad, 2 ); } else if( property->value <= 15 ) { quad = SETVAL_FRAME_RATE( quad, 3 ); } else if( property->value <= 30 ) { quad = SETVAL_FRAME_RATE( quad, 4 ); } else if( property->value <= 60 ) { quad = SETVAL_FRAME_RATE( quad, 5 ); } else if( property->value <= 120 ) { quad = SETVAL_FRAME_RATE( quad, 6 ); } else if( property->value <= 240 ) { quad = SETVAL_FRAME_RATE( quad, 7 ); } else { status = STATUS_INVALID_PARAMETER; TRACE( "dcam: invalid frame rate" ); } if( SUCCESS( status ) ) { int was_running = 0; if( dcamhandle->capture_running ) { status = dcam_capture_stop( dcamhandle ); was_running = 1; } if( SUCCESS( status ) ) { status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x600, quad ); if( SUCCESS( status ) ) { dcamhandle->current_frame_rate = GETVAL_FRAME_RATE( quad ); dcamhandle->current_iso_index = dcamhandle->current_iso_base_index + dcamhandle->current_frame_rate; if( was_running ) { status = dcam_capture_start( dcamhandle ); } } } } return status; } unicap_status_t dcam_get_frame_rate_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_SUCCESS; quadlet_t rate; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x600, &rate ); if( !SUCCESS( status ) ) { return status; } switch( GETVAL_FRAME_RATE( rate ) ) { case 0: property->value = 1.875; break; case 1: property->value = 3.75; break; case 2: property->value = 7.5; break; case 3: property->value = 15; break; case 4: property->value = 30; break; case 5: property->value = 60; break; case 6: property->value = 120; break; case 7: property->value = 240; break; default: TRACE( "dcam: unsupported frame rate\n" ); status = STATUS_FAILURE; break; } return status; } /* Set white balance mode: AUTO or ONE_PUSH */ unicap_status_t dcam_set_white_balance_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_FAILURE; u_int64_t flags = property->flags; quadlet_t quad = 0; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, ( dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset ), &quad ); flags &= property->flags_mask; quad = SETFLAG_AUTO( quad, 0 ); quad = SETFLAG_ONE_PUSH( quad, 0 ); if( SUCCESS( status ) ) { if( flags & UNICAP_FLAGS_AUTO ) { quad = SETFLAG_AUTO( quad, 1 ); // set auto mode flag } if( flags & UNICAP_FLAGS_ONE_PUSH ) { quad = SETFLAG_ONE_PUSH( quad, 1); // set one_push flag } quad = SETFLAG_ON_OFF( quad, 1 ); // set on_off flag quad = SETFLAG_PRESENCE( quad, 1 ); // set presence flag status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, ( dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset ), quad ); } return status; } /* set a property to the camera input: property dcam_property output: dcam_property: the cached value of the property is updated */ unicap_status_t dcam_set_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { unicap_status_t status = STATUS_FAILURE; switch( dcam_property->type ) { case PPTY_TYPE_BRIGHTNESS: case PPTY_TYPE_WHITEBAL_U: case PPTY_TYPE_WHITEBAL_V: case PPTY_TYPE_TEMPERATURE: { u_int64_t flags = property->flags; quadlet_t quad = 0; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, ( dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset ), &quad ); flags &= property->flags_mask; quad = SETFLAG_AUTO( quad, 0 ); quad = SETFLAG_ONE_PUSH( quad, 0 ); if( flags & UNICAP_FLAGS_MANUAL ) { unsigned int register_value; /* register_value = (property->value * (max-min)) + min; */ register_value = property->value; if( ( dcam_property->type != PPTY_TYPE_WHITEBAL_U ) && ( dcam_property->type != PPTY_TYPE_TEMPERATURE ) ) { quad = SETVAL_VALUE( quad, register_value ); } else if( ( dcam_property->type == PPTY_TYPE_WHITEBAL_U ) || ( dcam_property->type == PPTY_TYPE_TEMPERATURE ) ) { quad = SETVAL_U_VALUE( quad, register_value ); } } if( flags & UNICAP_FLAGS_AUTO ) { quad = SETFLAG_AUTO( quad, 1 ); // set auto mode flag } if( flags & UNICAP_FLAGS_ONE_PUSH ) { quad = SETFLAG_ONE_PUSH( quad, 1); // set one_push flag } quad = SETFLAG_ON_OFF( quad, 1 ); // set on_off flag quad = SETFLAG_PRESENCE( quad, 1 ); // set presence flag TRACE( "dcam_set_property quad: %08x\n", quad ); status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, ( dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset ), quad ); } break; case PPTY_TYPE_TRIGGER: { int i; quadlet_t quad = 0; quad = SETFLAG_PRESENCE( quad, 1 ); if( !strncmp( property->menu_item, dcam_trigger_modes[0], 127 ) ) { quad = SETFLAG_ON_OFF( quad, 0 ); } else { for( i = 1; i < dcamhandle->trigger_mode_count; i++ ) { if( !strncmp( property->menu_item, dcam_trigger_modes[i], 127 ) ) { // set mode quad |= ( ( i - 1 ) << 12 ); quad = SETFLAG_ON_OFF( quad, 1 ); break; } } } status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, ( dcamhandle->command_regs_base + 0x830 ), quad ); } break; case PPTY_TYPE_TRIGGER_POLARITY: { int i; quadlet_t quad = 0; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x830, &quad ); if( !SUCCESS( status ) ) { break; } quad &= ~(1<<26); if( !strcmp( property->menu_item, dcamhandle->trigger_polarities[1] ) ) { quad |= (1<<26); } status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, ( dcamhandle->command_regs_base + 0x830 ), quad ); } break; case PPTY_TYPE_REGISTER: { dcam_raw_register_t *data = ( dcam_raw_register_t *)property->property_data; if( property->property_data_size < sizeof( dcam_raw_register_t ) ) { status = STATUS_INVALID_PARAMETER; } else { status = _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + data->address, data->value ); } } break; default: { TRACE( "dcam: Unknown property type\n" ); } break; } return status; } unicap_status_t dcam_get_white_balance_mode_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t val = 0; unicap_status_t status = STATUS_SUCCESS; if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, &val ) < 0 ) { return STATUS_FAILURE; } if( GETFLAG_AUTO(val) ) { property->flags |= UNICAP_FLAGS_AUTO; } if( GETFLAG_ON_OFF(val) ) { property->flags |= UNICAP_FLAGS_ON_OFF; } if( GETFLAG_ONE_PUSH(val) ) { property->flags |= UNICAP_FLAGS_ONE_PUSH; } return status; } /* get property from the camera input: property: property->identifier specifies property to get output: property: all values updated to represent current state of camera */ unicap_status_t dcam_get_property( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ) { quadlet_t val = 0; unicap_status_t status = STATUS_SUCCESS; if( ( dcam_property->type != PPTY_TYPE_REGISTER ) && ( dcam_property->type != PPTY_TYPE_FRAMERATE ) ) { if( _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x800 + dcam_property->register_offset, &val ) < 0 ) { return STATUS_FAILURE; } } // initialize property struct // TODO: correct initialization if( strcmp( property->identifier, "register" ) ) { memcpy( property, &dcam_property->unicap_property, sizeof( unicap_property_t ) ); } switch( dcam_property->type ) { case PPTY_TYPE_BRIGHTNESS: case PPTY_TYPE_WHITEBAL_U: case PPTY_TYPE_WHITEBAL_V: case PPTY_TYPE_TEMPERATURE: { if( GETFLAG_AUTO(val) ) { property->flags |= UNICAP_FLAGS_AUTO; property->flags &= ~UNICAP_FLAGS_MANUAL; } else { property->flags |= UNICAP_FLAGS_MANUAL; } if( GETFLAG_ON_OFF(val) ) { property->flags |= UNICAP_FLAGS_ON_OFF; } if( GETFLAG_ONE_PUSH(val) ) { property->flags |= UNICAP_FLAGS_ONE_PUSH; } if( ( dcam_property->type == PPTY_TYPE_BRIGHTNESS ) || ( dcam_property->type == PPTY_TYPE_WHITEBAL_U ) || ( dcam_property->type == PPTY_TYPE_WHITEBAL_V ) ) { unsigned int min = GETVAL_MIN_VALUE( dcam_property->register_inq); unsigned int max = GETVAL_MAX_VALUE( dcam_property->register_inq); if( ( dcam_property->type != PPTY_TYPE_WHITEBAL_U ) && ( dcam_property->type != PPTY_TYPE_TEMPERATURE ) ) { unsigned int register_value = GETVAL_VALUE( val ); /* double d_value = ( double )( register_value - min ) / ( max - min ); */ property->value = register_value; } else if ( dcam_property->type == PPTY_TYPE_WHITEBAL_U ) { unsigned int register_value; register_value = GETVAL_U_VALUE( val ); /* d_value = ( double )( register_value - min ) / (double)( max - min ); */ property->value = register_value; } else if ( dcam_property->type == PPTY_TYPE_TEMPERATURE ) { double d_value; unsigned int register_value; register_value = GETVAL_VALUE( val ); d_value = ( double )( register_value - min ) / ( max - min ); property->value = d_value; } } } break; case PPTY_TYPE_FRAMERATE: { } break; case PPTY_TYPE_TRIGGER: { quadlet_t trigger; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x830, &trigger ); if( !SUCCESS( status ) ) { break; } // if we have a data buffer for the optional parameter if( property->property_data_size >= 4 ) { if( property->property_data ) { ((unsigned int *)property->property_data)[0] = GETVAL_VALUE( trigger ); } else { status = STATUS_INVALID_PARAMETER; break; } } if( !GETFLAG_ON_OFF( trigger ) ) { strncpy( property->menu_item, dcam_trigger_modes[0], 127 ); } else { int mode = 0; mode = ( trigger >> 12 ) & 0xf; strncpy( property->menu_item, dcam_trigger_modes[ mode+1 ], 127 ); } property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; } break; case PPTY_TYPE_TRIGGER_POLARITY: { quadlet_t trigger; status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x830, &trigger ); if( !SUCCESS( status ) ) { break; } strcpy( property->menu_item, dcamhandle->trigger_polarities[( dcam_property->register_default >> 26 ) & 1] ); property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; } break; case PPTY_TYPE_REGISTER: { dcam_raw_register_t *data = ( dcam_raw_register_t * )property->property_data; if( property->property_data_size < sizeof( dcam_raw_register_t ) ) { status = STATUS_INVALID_PARAMETER; } else { status = _dcam_read_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + data->address, &data->value ); } } break; default: { TRACE( "dcam: unknown ppty type\n" ); } break; } return status; } /* returns 1 if the given rate is available in the frame rate inquiry register quad, 0 otherwise */ int _dcam_check_frame_rate_available( quadlet_t quad, int rate ) { TRACE( "check frame rate avail: quad= %08x, rate: %d := %d\n", quad, rate, ( quad >> (31-rate) ) & 1 ); return ( quad >> ( 31 - rate ) ) & 1; } dcam_property_t *dcam_copy_property( dcam_property_t *dest, dcam_property_t *src ) { dest->id = src->id; unicap_copy_property( &dest->unicap_property, &src->unicap_property ); dest->register_offset = src->register_offset; dest->register_inq = src->register_inq; dest->register_default = src->register_default; dest->register_value = src->register_value; dest->type = src->type; dest->feature_hi_mask = src->feature_hi_mask; dest->feature_lo_mask = src->feature_lo_mask; dest->set_function = src->set_function; dest->get_function = src->get_function; dest->init_function = src->init_function; return dest; } libunicap/cpi/dcam/dcam_functions.c0000644000175000017500000005054113164711411020101 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif #include // ntohl() #include #include #include #include #include #include #include "dcam.h" #include "dcam_functions.h" #if DCAM_DEBUG #define DEBUG #endif #include "debug.h" #define MAX_RETRIES 5 #define REGISTER_DELAY 5000 // usec static nodeaddr_t _dcam_get_vendor_name_leaf_address( raw1394handle_t raw1394handle, int node, nodeaddr_t logical_unit_dir_addr ); static nodeaddr_t _dcam_get_model_name_leaf_address( raw1394handle_t raw1394handle, int node, nodeaddr_t logical_unit_dir_addr ); int _dcam_read_register( raw1394handle_t raw1394handle, int node, nodeaddr_t address, quadlet_t *value ) { int retval; int retries = MAX_RETRIES; dcam_handle_t dcamhandle = raw1394_get_userdata( raw1394handle ); if( dcamhandle != NULL ) { struct timeval ctime; unsigned long time = 0; gettimeofday( &ctime, 0 ); time = 1000000 * ( ctime.tv_sec - dcamhandle->last_register_access.tv_sec ); time += ctime.tv_usec - dcamhandle->last_register_access.tv_usec; if( time < REGISTER_DELAY ) { /* TRACE( "Trying to access camera too fast. Sleeping: %d\n", REGISTER_DELAY - time ); */ usleep( REGISTER_DELAY - time ); } memcpy( &dcamhandle->last_register_access, &ctime, sizeof( struct timeval ) ); } while( retries-- ) { retval = raw1394_read( raw1394handle, 0xffc0 | node, address, 4, value ); /* TRACE( "read[%d] addr: %llx : %08x\n", node, address, *value ); */ if( !retval ) { *value = ntohl( *value ); return 0; } if( errno == 22 ) { // invalid arg return -1; } /* TRACE( "retval: %d, error: %d %s\n", retval, errno, strerror( errno ) ) */ usleep( REGISTER_DELAY ); } return -1; } int _dcam_write_register( raw1394handle_t raw1394handle, int node, nodeaddr_t address, quadlet_t value ) { int retval; int retries = MAX_RETRIES; dcam_handle_t dcamhandle = raw1394_get_userdata( raw1394handle ); if( dcamhandle ) { struct timeval ctime; unsigned long time = 0; gettimeofday( &ctime, 0 ); time = 1000000 * ( ctime.tv_sec - dcamhandle->last_register_access.tv_sec ); time += ctime.tv_usec - dcamhandle->last_register_access.tv_usec; if( time < REGISTER_DELAY ) { /* TRACE( "Trying to access camera too fast. Sleeping: %d\n", REGISTER_DELAY - time ); */ usleep( REGISTER_DELAY - time ); } memcpy( &dcamhandle->last_register_access, &ctime, sizeof( struct timeval ) ); } value = ntohl( value ); while( retries-- ) { /* TRACE( "write addr: %llx : %08x\n", address, value ); */ retval = raw1394_write( raw1394handle, 0xffc0 | node, address, 4, &value ); if( !retval ) { return 0; } usleep( REGISTER_DELAY ); } return -1; } int _dcam_get_directory_count( raw1394handle_t raw1394handle, int node ) { nodeaddr_t addr = CSR_REGISTER_BASE + CSR_CONFIG_ROM; quadlet_t root_dir_length, val; unsigned int offset; int count = 0; if( _dcam_read_register( raw1394handle, node, addr, &root_dir_length ) < 0 ) { TRACE( "failed to read length register %llx\n", addr ); return 0; } /* TRACE( "root_dir_length: %llx %x\n", addr, root_dir_length ); */ root_dir_length &=0x00ff0000; root_dir_length = root_dir_length>>16; for( offset = 8; offset < (root_dir_length*4); offset+=4 ) { if( _dcam_read_register( raw1394handle, node, addr + offset, &val ) == 0 ) { /* TRACE( "offset: %x \t%x\n", offset, val ); */ if( ( val & 0xff000000 )>>24 == 0xd1 ) { count++; } } } return count; } nodeaddr_t _dcam_get_unit_directory_address( raw1394handle_t raw1394handle, int node, int directory ) { nodeaddr_t addr = CSR_REGISTER_BASE + CSR_CONFIG_ROM; quadlet_t root_dir_length, val; unsigned int offset; int count = 0; if( _dcam_read_register( raw1394handle, node, addr, &root_dir_length ) < 0 ) { return 0; } root_dir_length &= 0x00ff0000; root_dir_length = root_dir_length >> 16; // scan through the root directory for( offset = 8; offset < (root_dir_length*4); offset+=4 ) { if( _dcam_read_register( raw1394handle, node, addr + offset, &val ) == 0 ) { if( (( val & 0xff000000 )>>24) == 0xd1 ) { //found a unit directory if( count == directory ) { break; } count++; } } else { return 0; } } // calculate unit directory address addr += offset; addr += (val & 0xffffff)*4; return addr; } nodeaddr_t _dcam_calculate_address( raw1394handle_t raw1394handle, int node, nodeaddr_t addr, quadlet_t key ) { quadlet_t dir_length, val; unsigned int offset; if( _dcam_read_register( raw1394handle, node, addr, &dir_length ) < 0 ) { return 0; } /* TRACE( "calc addr: %llx\t%08x\n", addr, dir_length ); */ dir_length = dir_length >> 16; for( offset = 0; offset < ( dir_length * 4 ); offset += 4 ) { if( _dcam_read_register( raw1394handle, node, addr + offset, &val ) < 0 ) { return 0; } /* TRACE( "off: %x\t%08x\n", offset, val ); */ if( (( val & 0xff000000 )>>24) == key ) { val &= ~0xff000000; break; } } if( offset > ( dir_length * 4 ) ) { return 0; } addr += offset; return addr; } nodeaddr_t _dcam_get_unit_dependent_directory_address( raw1394handle_t raw1394handle, int node, int directory ) { nodeaddr_t addr = _dcam_get_unit_directory_address( raw1394handle, node, directory ); // val now contains 0xd4xxxxxx where xxxxxx is unit_dependent_directory offset addr = _dcam_calculate_address( raw1394handle, node, addr, 0xd4 ); return addr; } static nodeaddr_t _dcam_get_vendor_name_leaf_address( raw1394handle_t raw1394handle, int node, nodeaddr_t logical_unit_dir_addr ) { nodeaddr_t addr; quadlet_t val; if( !logical_unit_dir_addr ) { return 0; } logical_unit_dir_addr = _dcam_calculate_address( raw1394handle, node, logical_unit_dir_addr, 0xd4 ); if( !logical_unit_dir_addr ) { return 0; } if( _dcam_read_register( raw1394handle, node, logical_unit_dir_addr, &val ) < 0 ) { return 0; } logical_unit_dir_addr += val &0xffff*4; addr = _dcam_calculate_address( raw1394handle, node, logical_unit_dir_addr, 0x81 ); if( !addr ) { return 0; } if( _dcam_read_register( raw1394handle, node, addr, &val ) < 0 ) { return 0; } addr += (val&0xffff)*4; return addr; } static nodeaddr_t _dcam_get_model_name_leaf_address( raw1394handle_t raw1394handle, int node, nodeaddr_t logical_unit_dir_addr ) { nodeaddr_t addr; quadlet_t val; logical_unit_dir_addr = _dcam_calculate_address( raw1394handle, node, logical_unit_dir_addr, 0xd4 ); _dcam_read_register( raw1394handle, node, logical_unit_dir_addr, &val ); logical_unit_dir_addr += val &0xffff*4; addr = _dcam_calculate_address( raw1394handle, node, logical_unit_dir_addr, 0x81 ); addr += 4; // hack!! assume model name leaf addr follows vendor name leaf addr. _dcam_read_register( raw1394handle, node, addr, &val ); addr += (val&0xffff)*4; return addr; } unsigned int _dcam_get_spec_ID( raw1394handle_t raw1394handle, int node, nodeaddr_t unit_directory_addr ) { quadlet_t spec_ID; nodeaddr_t addr; TRACE( "Get spec ID\n" ); addr = _dcam_calculate_address( raw1394handle, node, unit_directory_addr, 0x12 ); if( addr == 0 ) { TRACE( "!addr\n" ); return 0; } _dcam_read_register( raw1394handle, node, addr, &spec_ID ); // spec_ID now contains 0x12xxxxxx where xxxxxx is spec_ID spec_ID &= ~0xff000000; return spec_ID; } unsigned int _dcam_get_sw_version( raw1394handle_t raw1394handle, int node, nodeaddr_t unit_directory_addr ) { quadlet_t sw_version; nodeaddr_t addr; addr = _dcam_calculate_address( raw1394handle, node, unit_directory_addr, 0x13 ); if( !addr ) { return 0; } _dcam_read_register( raw1394handle, node, addr, &sw_version ); // sw_version now contains 0x13xxxxxx where xxxxxx is sw_version sw_version &= ~0xff000000; return sw_version; } nodeaddr_t _dcam_get_command_regs_base( raw1394handle_t raw1394handle, int node, nodeaddr_t unit_dependend_directory_addr ) { quadlet_t offset; nodeaddr_t addr; addr = _dcam_calculate_address( raw1394handle, node, unit_dependend_directory_addr, 0xd4 ); if( !addr ) { return 0; } _dcam_read_register( raw1394handle, node, addr, &offset ); offset &= ~0xff000000; addr = _dcam_calculate_address( raw1394handle, node, addr + (offset*4), 0x40 ); _dcam_read_register( raw1394handle, node, addr, &offset ); offset &= ~0xff000000; addr = CSR_REGISTER_BASE; addr += offset*4; return addr; } int _dcam_get_vendor_id( raw1394handle_t raw1394handle, int node, int directory, unsigned long *vendor_id ) { quadlet_t node_vendor_id; _dcam_read_register( raw1394handle, node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0xc, &node_vendor_id ); node_vendor_id = node_vendor_id >> 8; *vendor_id = node_vendor_id; return STATUS_SUCCESS; } int _dcam_get_model_id( raw1394handle_t raw1394handle, int node, int directory, unsigned long *model_id_hi, unsigned long *model_id_lo ) { quadlet_t node_model_id; _dcam_read_register( raw1394handle, node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0xc, &node_model_id ); *model_id_hi = node_model_id & 0xff; _dcam_read_register( raw1394handle, node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 0x10, &node_model_id ); *model_id_lo = node_model_id; return STATUS_SUCCESS; } int _dcam_read_name_leaf( raw1394handle_t raw1394handle, int node, nodeaddr_t addr, char *buffer, size_t *buffer_len ) { quadlet_t leaf_length; int i; if( _dcam_read_register( raw1394handle, node, addr, &leaf_length ) < 0 ) { return -1; } leaf_length = leaf_length >> 16; leaf_length -= 2; if( ( leaf_length * 4 +1) > *buffer_len ) { *buffer_len = leaf_length * 4; return -1; } for( i=0; ( i < leaf_length ) && ( i < (*buffer_len / 4 ) ); i++ ) { quadlet_t val; if( _dcam_read_register( raw1394handle, node, addr + 0xc + (i*4), &val ) < 0 ) { return -1; } val = ntohl( val ); memcpy(buffer+(i*4), &val, 4 ); } buffer[leaf_length*4]=0; *buffer_len = leaf_length * 4; return *buffer_len; } static int _dcam_check_compat_fast( raw1394handle_t raw1394handle, int node ) { nodeaddr_t addr = CSR_REGISTER_BASE + CSR_CONFIG_ROM; unsigned int spec_ID; unsigned int sw_version; quadlet_t quad; int unit_offset; int key; addr += 0x24; if( _dcam_read_register( raw1394handle, node, addr, &quad ) < 0 ) { return 0; } unit_offset = ( quad & 0xffffff ) * 4; addr += unit_offset; if( _dcam_read_register( raw1394handle, node, addr + 0x4, &quad ) < 0 ) { return 0; } spec_ID = quad & 0xffffff; key = ( quad >> 24 ) & 0xff; if( key != 12 ) { return 0; } if( spec_ID != 0xA02D ) { return -1; } if( _dcam_read_register( raw1394handle, node, addr + 0x8, &quad ) < 0 ) { return 0; } sw_version = quad & 0xffffff; if( ( sw_version < 0x100 ) || ( sw_version > 0x103 ) ) { return -1; } return 1; } int _dcam_is_compatible( raw1394handle_t raw1394handle, int node, int directory ) { unsigned int spec_ID; unsigned int sw_version; int fastcheck; if( directory == 0 ) { fastcheck = _dcam_check_compat_fast( raw1394handle, node ); if( fastcheck == 1 ) { TRACE( "fast check success\n" ); return 1; } else if( fastcheck < 0 ) { TRACE( "fastcheck incompatible\n" ); return 0; } } spec_ID = _dcam_get_spec_ID( raw1394handle, node, _dcam_get_unit_directory_address( raw1394handle, node, directory ) ); if( spec_ID != 0xa02d ) { TRACE( "!spec_id\n" ); return 0; } sw_version = _dcam_get_sw_version( raw1394handle, node, _dcam_get_unit_directory_address( raw1394handle, node, directory ) ); if( ( sw_version < 0x100 ) || ( sw_version > 0x103 ) ) { TRACE( "!sw_ver\n" ); return 0; } return 1; } void _dcam_create_device_identifier( char *buffer, size_t size, char *vendor_name, char *model_name, unsigned long model_id_hi, unsigned long model_id_lo ) { snprintf( buffer, size, "%s %s %lu%lu", vendor_name, model_name, model_id_hi, model_id_lo ); } unicap_status_t _dcam_get_device_info( raw1394handle_t raw1394handle, int node, int directory, unicap_device_t *device ) { char buffer[128]; size_t buffer_size = 128; unsigned long model_id_hi; unsigned long model_id_lo; unsigned long vendor_id; nodeaddr_t addr; nodeaddr_t logical_unit_dir_addr; TRACE( "GetDevInfo\n" ); strcpy( device->device, "/dev/raw1394" ); logical_unit_dir_addr = _dcam_get_unit_directory_address( raw1394handle, node, directory ); if( !logical_unit_dir_addr ) { return STATUS_FAILURE; } addr = _dcam_get_vendor_name_leaf_address( raw1394handle, node, logical_unit_dir_addr ); if( !addr ) { TRACE( "Get vendor name lead addr failed\n" ); return STATUS_FAILURE; } if( _dcam_read_name_leaf( raw1394handle, node, addr, buffer, &buffer_size ) < 0 ) { TRACE( "Read name leaf failed\n" ); return STATUS_FAILURE; } strcpy( device->vendor_name, buffer ); buffer_size = 128; addr = _dcam_get_model_name_leaf_address( raw1394handle, node, logical_unit_dir_addr ); if( !addr ) { return STATUS_FAILURE; } if( _dcam_read_name_leaf( raw1394handle, node, addr, buffer, &buffer_size ) < 0 ) { TRACE( "-->\n" ); return STATUS_FAILURE; } strcpy( device->model_name, buffer ); _dcam_get_vendor_id( raw1394handle, node, directory, &vendor_id ); _dcam_get_model_id( raw1394handle, node, directory, &model_id_hi, &model_id_lo ); _dcam_create_device_identifier( buffer, 128, device->vendor_name, device->model_name, model_id_hi, model_id_lo ); strcpy( device->identifier, buffer ); device->model_id = ((unsigned long long )model_id_hi << 32) | (unsigned long long )model_id_lo; device->vendor_id = vendor_id; TRACE( "-->\n" ); return STATUS_SUCCESS; } unicap_status_t _dcam_find_device( unicap_device_t *device, int *_port, int *_node, int *_directory ) { raw1394handle_t raw1394handle; int port; int node; int directory; struct raw1394_portinfo portinfo[16]; int port_count; raw1394handle = raw1394_new_handle( ); if( !raw1394handle ) { return STATUS_FAILURE; } port_count = raw1394_get_port_info( raw1394handle, portinfo, 16 ); if( port_count < 0 ) { raw1394_destroy_handle( raw1394handle ); return STATUS_FAILURE; } if( port_count == 0 ) { raw1394_destroy_handle( raw1394handle ); return STATUS_NO_DEVICE; } raw1394_destroy_handle( raw1394handle ); for( port = 0; port < port_count; port++ ) { if( ( raw1394handle = raw1394_new_handle_on_port( port ) ) == NULL ) { continue; } raw1394_set_userdata( raw1394handle, 0 ); for( node = 0; node < raw1394_get_nodecount( raw1394handle ); node ++ ) { for( directory = 0; directory < _dcam_get_directory_count( raw1394handle, node ); directory++ ) { if( _dcam_is_compatible( raw1394handle, node, directory ) ) { int match = 1; if( strlen( device->identifier ) ) { char identifier[128]; char vendor_name[128]; char model_name[128]; size_t size = 128; unsigned long model_id_hi, model_id_lo; nodeaddr_t logical_unit_dir_addr; nodeaddr_t addr; logical_unit_dir_addr = _dcam_get_unit_directory_address( raw1394handle, node, directory ); if( !logical_unit_dir_addr ) { TRACE( "Failed to get logical unit addr\n" ); match = 0; continue; } addr = _dcam_get_vendor_name_leaf_address( raw1394handle, node, logical_unit_dir_addr ); if( !addr ) { TRACE( "Failed to get vendor name leaf addr\n" ); match = 0; continue; } _dcam_get_model_id( raw1394handle, node, directory, &model_id_hi, &model_id_lo ); _dcam_read_name_leaf( raw1394handle, node, addr, vendor_name, &size ); size = 128; addr = _dcam_get_model_name_leaf_address( raw1394handle, node, logical_unit_dir_addr ); if( !addr ) { TRACE( "Failed to get model name leaf addr\n" ); match = 0; continue; } _dcam_read_name_leaf( raw1394handle, node, addr, model_name, &size ); _dcam_create_device_identifier( identifier, 128, vendor_name, model_name, model_id_hi, model_id_lo ); if( !strcmp( identifier, device->identifier ) ) { match = 1; *_port = port; *_node = node; *_directory = directory; raw1394_destroy_handle( raw1394handle ); return STATUS_SUCCESS; } else { match = 0; continue; } }// strlen( device->identifier if( strlen( device->vendor_name ) ) { char vendor_name[128]; size_t size = 128; nodeaddr_t logical_unit_dir_addr; nodeaddr_t addr; logical_unit_dir_addr = _dcam_get_unit_directory_address( raw1394handle, node, directory ); if( !logical_unit_dir_addr ) { TRACE( "Failed to get logical unit addr\n" ); match = 0; continue; } addr = _dcam_get_vendor_name_leaf_address( raw1394handle, node, logical_unit_dir_addr ); _dcam_read_name_leaf( raw1394handle, node, addr, vendor_name, &size ); if( !strcmp( vendor_name, device->vendor_name ) ) { match = 1; } else { match = 0; continue; } }//strlen( device->vendor_name if( strlen( device->model_name ) ) { char model_name[128]; size_t size = 128; nodeaddr_t logical_unit_dir_addr; nodeaddr_t addr; logical_unit_dir_addr = _dcam_get_unit_directory_address( raw1394handle, node, directory ); if( !logical_unit_dir_addr ) { TRACE( "Failed to get logical unit addr\n" ); match = 0; continue; } addr = _dcam_get_model_name_leaf_address( raw1394handle, node, logical_unit_dir_addr ); if( !addr ) { match = 0; continue; } _dcam_read_name_leaf( raw1394handle, node, addr, model_name, &size ); if( !strcmp( model_name, device->model_name ) ) { match = 1; } else { match = 0; continue; } } if( device->vendor_id != -1 ) { unsigned long vendor_id; _dcam_get_vendor_id( raw1394handle, node, directory, &vendor_id ); if( device->vendor_id == vendor_id ) { match = 1; } else { match = 0; continue; } } if( device->model_id != -1 ) { unsigned long long model_id; unsigned long model_id_hi; unsigned long model_id_lo; _dcam_get_model_id( raw1394handle, node, directory, &model_id_hi, &model_id_lo ); model_id = (unsigned long long)model_id_hi << 32 | (unsigned long long )model_id_lo; if( device->model_id == model_id ) { match = 1; } else { match = 0; continue; } } if( match ) { *_port = port; *_node = node; *_directory = directory; raw1394_destroy_handle( raw1394handle ); return STATUS_SUCCESS; } } } } if( raw1394handle ) { raw1394_destroy_handle( raw1394handle ); } } return STATUS_NO_DEVICE; } libunicap/cpi/dcam/dcam.h0000644000175000017500000001517313164711411016020 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_H__ #define __DCAM_H__ #include #include #include #include #ifdef RAW1394_1_1_API #include #include #endif #ifdef RAW1394_1_0_API #include #include #endif #include #include #include "queue.h" typedef struct _dcam_handle *dcam_handle_t; #include "dcam_juju.h" #define S100 0 #define S200 1 #define S400 2 #define S800 3 #define S1600 4 #define S3200 5 #define DCAM_NUM_DMA_BUFFERS 8 #define DCAM_DMA_NONE 0 #define DCAM_DMA_VIDEO1394 1 #define DCAM_DMA_JUJU 2 enum dcam_property_enum { DCAM_PPTY_BRIGHTNESS = 0, DCAM_PPTY_ABS_FOCUS, DCAM_PPTY_ABS_ZOOM, DCAM_PPTY_INIT_LENS, DCAM_PPTY_AUTO_EXPOSURE, DCAM_PPTY_SHARPNESS, DCAM_PPTY_WHITE_BALANCE_MODE, DCAM_PPTY_WHITE_BALANCE_U, DCAM_PPTY_WHITE_BALANCE_V, DCAM_PPTY_HUE, DCAM_PPTY_SATURATION, DCAM_PPTY_GAMMA, DCAM_PPTY_SHUTTER, DCAM_PPTY_GAIN, DCAM_PPTY_IRIS, DCAM_PPTY_FOCUS, DCAM_PPTY_TEMPERATURE, DCAM_PPTY_SOFTWARE_TRIGGER, DCAM_PPTY_TRIGGER_MODE, DCAM_PPTY_TRIGGER_POLARITY, DCAM_PPTY_ZOOM, DCAM_PPTY_PAN, DCAM_PPTY_TILT, DCAM_PPTY_OPTICAL_FILTER, DCAM_PPTY_CAPTURE_QUALITY, DCAM_PPTY_FRAME_RATE, DCAM_PPTY_RW_REGISTER, DCAM_PPTY_TIMEOUT, DCAM_PPTY_GPIO, DCAM_PPTY_STROBE, DCAM_PPTY_STROBE_MODE, DCAM_PPTY_STROBE_DURATION, DCAM_PPTY_STROBE_DELAY, DCAM_PPTY_STROBE_POLARITY, DCAM_PPTY_ENABLE_FRAME_DROP, DCAM_PPTY_FRAME_DROP_COUNT, DCAM_PPTY_END }; typedef enum dcam_property_enum dcam_property_enum_t; typedef struct _dcam_property dcam_property_t; typedef unicap_status_t (* dcam_property_func_t) ( dcam_handle_t dcamhandle, unicap_property_t *property, dcam_property_t *dcam_property ); struct _dcam_property { dcam_property_enum_t id; unicap_property_t unicap_property; u_int32_t register_offset; u_int32_t absolute_offset; quadlet_t register_inq; // content of inquiry register quadlet_t register_default; // initial content of cntl register quadlet_t register_value; // cached content of cntl register u_int32_t type; // PPTY_TYPE quadlet_t feature_hi_mask; quadlet_t feature_lo_mask; dcam_property_func_t set_function; dcam_property_func_t get_function; dcam_property_func_t init_function; }; struct _dcam_handle { raw1394handle_t raw1394handle; int port; int node; int directory; unicap_device_t unicap_device; int allocate_bandwidth; nodeaddr_t command_regs_base; // base address of the command registers int v_format_count; unicap_format_t v_format_array[3*8]; int dma_fd; // unsigned char *dma_buffer; // the ring buffer for video1394 dma capture size_t dma_buffer_size; //size of one dma_buffer int current_dma_capture_buffer; // int use_dma; // flags: 1 == use video1394 0 == use raw1394 int dma_vmmap_frame_size; uint32_t juju_iso_handle; dcam_juju_buffer_t juju_buffers[DCAM_NUM_DMA_BUFFERS]; int timeout_seconds; int current_format_index; // index of this format in the v_format_array int current_iso_index; // index of this format in the isoch table int current_iso_base_index; // index in isoch_table without frame rate int current_frame_rate; // int channel_allocated; // current channel int bandwidth_allocated; // current bandwidth unicap_buffer_type_t buffer_type; // user or system pointers dcam_property_t *dcam_property_table; quadlet_t feature_hi; quadlet_t feature_lo; char* trigger_modes[5]; // list of trigger modes supported by the camera int trigger_mode_count; unsigned int trigger_parameter; // char *trigger_polarities[2]; volatile int device_present; // set to 1 on device open and set to 0 by the bus reset handler if the device is removed volatile int capture_running; // set to 1 on capture start, reset to 0 on stop or error conditions pthread_t capture_thread; // handle of the thread to handle raw1394 capturing pthread_t timeout_thread; // thread to wake up raw1394_loop_iterate regularly for timeouts pthread_t dma_capture_thread; int dma_capture_thread_quit; int wait_for_sy; // used by raw1394 iso handler unsigned int current_buffer_offset; // used by raw1394 iso handler unsigned int buffer_size; // size of one frame struct _unicap_queue *current_buffer; // currently filled buffer struct _unicap_queue input_queue; struct _unicap_queue output_queue; struct timeval last_register_access; struct timeval current_fill_end_time; struct timeval current_fill_start_time; unicap_event_callback_t event_callback; unicap_handle_t unicap_handle; unsigned int frame_drop_count; int enable_frame_drop; }; struct _dcam_isoch_mode { unsigned int bytes_per_frame; unsigned int bytes_per_packet; unsigned int min_speed; }; /* definitions for property types */ enum _dcam_ppty_type_enum { PPTY_TYPE_BRIGHTNESS=1, PPTY_TYPE_WHITEBAL_U, PPTY_TYPE_WHITEBAL_V, PPTY_TYPE_TEMPERATURE, PPTY_TYPE_TRIGGER, PPTY_TYPE_TRIGGER_POLARITY, PPTY_TYPE_FRAMERATE, PPTY_TYPE_REGISTER }; extern dcam_property_t _dcam_properties[]; union _abs_value { quadlet_t quad; float f; }; typedef union _abs_value abs_value_t; /**********************************************************************************************************/ /* Function prototypes */ unicap_status_t dcam_capture_stop( void *cpi_data ); unicap_status_t dcam_capture_start( void *cpi_data ); #ifdef PERTIMING struct timeval starttime; struct timeval endtime; #define TIME(name,x) {gettimeofday( &starttime, NULL );}{x}{\ gettimeofday( &endtime, NULL );\ if( ( endtime.tv_usec - starttime.tv_usec ) < 0 )\ {\ endtime.tv_usec += 1000000;\ endtime.tv_sec--;\ }\ endtime.tv_usec -= starttime.tv_usec;\ endtime.tv_sec -= starttime.tv_sec;\ printf( "timed '%s': %ds:%dms\n", name,endtime.tv_sec, endtime.tv_usec/1000 );\ } #else #define TIME(name,x) x #endif #endif//__DCAM_H__ libunicap/cpi/dcam/dcam_capture.h0000644000175000017500000000276513164711411017546 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DCAM_CAPTURE_H__ #define __DCAM_CAPTURE_H__ #include "dcam.h" void *dcam_dma_capture_thread( void *arg ); void *dcam_capture_thread( void * ); enum raw1394_iso_disposition dcam_iso_handler( raw1394handle_t raw1394handle, unsigned char *data, unsigned int len, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped ); unicap_status_t _dcam_dma_setup( dcam_handle_t dcamhandle ); unicap_status_t _dcam_dma_free( dcam_handle_t dcamhandle ); unicap_status_t _dcam_dma_unlisten( dcam_handle_t dcamhandle ); unicap_status_t dcam_dma_wait_buffer( dcam_handle_t dcamhandle ); #endif//__DCAM_CAPTURE_H__ libunicap/cpi/thing/0000755000175000017500000000000013164711411015141 5ustar zmoelnigzmoelniglibunicap/cpi/thing/queue.c0000644000175000017500000001046513164711411016437 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #ifdef DEBUG #include #endif #include "queue.h" #include #include void _dump_queue( struct _unicap_queue *queue ) { int i = 0; printf( "## dump queue\n" ); while( queue->next ) { printf( "entry: %d, addr: %p\n", i++, queue ); printf( "entry->next: %p\n", queue->next ); printf( "data: %p\n", queue->data ); printf( "sema: %p\n", queue->psema ); queue = queue->next; } printf( "entry: %d, addr: %p\n", i, queue ); printf( "entry->next: %p\n", queue->next ); printf( "data: %p\n", queue->data ); printf( "sema: %p\n\n", queue->psema ); } void _insert_back_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { struct _unicap_queue *tmp_queue; if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } tmp_queue = queue; // run to the end of the queue while( tmp_queue->next ) { tmp_queue = tmp_queue->next; } tmp_queue->next = entry; entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); return; } } void _insert_front_queue( struct _unicap_queue *queue, struct _unicap_queue *entry ) { if( !entry ) { return; } if( sem_wait( queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } entry->next = queue->next; entry->psema = queue->psema; queue->next = entry; if( sem_post( queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } struct _unicap_queue *_get_front_queue( struct _unicap_queue *queue ) { struct _unicap_queue *entry; if( sem_wait( queue->psema ) ) { TRACE( "sem_wait failed!\n" ); return 0; } if( !queue->next ) { entry = 0; sem_post( queue->psema ); goto out; } entry = queue->next; if( queue->next ) { queue->next = queue->next->next; } entry->psema = queue->psema; entry->next = 0; if( sem_post( entry->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } out: return entry; } void _move_to_queue( struct _unicap_queue *from_queue, struct _unicap_queue *to_queue ) { struct _unicap_queue *tmp_to_queue; struct _unicap_queue *tmp_from_queue; struct _unicap_queue *entry; if( sem_wait( from_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( sem_wait( to_queue->psema ) ) { TRACE( "FATAL: sem_wait failed\n" ); return; } if( !from_queue->next ) { entry = 0; goto out; } tmp_from_queue = from_queue; /////////////////////////////////////////////////////////////// entry = from_queue->next; if( tmp_from_queue->next ) { tmp_from_queue->next = tmp_from_queue->next->next; } entry->next = 0; ////////////////////////////////////////////////////////////// tmp_to_queue = to_queue; // run to the end of the queue while( tmp_to_queue->next ) { tmp_to_queue = tmp_to_queue->next; } tmp_to_queue->next = entry; entry->psema = to_queue->psema; out: if( sem_post( from_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } if( sem_post( to_queue->psema ) ) { TRACE( "FATAL: sem_post failed\n" ); } } void _init_queue( struct _unicap_queue *queue ) { memset( queue, 0, sizeof( struct _unicap_queue ) ); if( sem_init( &queue->sema, 0, 1 ) ) { TRACE( "FATAL: sem_init failed\n" ); } queue->psema = &queue->sema; } int _queue_get_size( struct _unicap_queue *queue ) { int entries = 0; struct _unicap_queue *entry = queue; /* TRACE( "entries: %d\n", entries ); */ while( entry->next ) { /* TRACE( "entries: %d\n", entries ); */ entries++; entry = entry->next; } return entries; } libunicap/cpi/thing/Makefile.am0000644000175000017500000000046313164711411017200 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in INCLUDES = -I../include -I../../include libcpi_LTLIBRARIES = libthing.la libcpidir = $(libdir)/unicap/cpi libthing_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ libthing_la_LIBADD = @PTHREAD_LIBS@ libthing_la_SOURCES = \ queue.c \ thing.c thing.h libunicap/cpi/thing/thing.c0000644000175000017500000004660313164711411016427 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* thing.c: test plugin for the unicap llibrary */ #include "config.h" #include #include #include #include #include #include #include #if THING_DEBUG #define DEBUG #endif #include #include #include #include "unicap_cpi_std_struct.h" #include "queue.h" #include "thing.h" #define THING_SYSTEM_BUFFERS 8 unicap_rect_t null_format_sizes[] = { { 0, 0, 320, 240 }, { 0, 0, 384, 288 }, { 0, 0, 640, 480 } }; unicap_format_t null_formats[] = { { identifier: "UYVY", // name size: { x: 0, y: 0, width: 320, height: 240}, min_size: { x: 0, y: 0, width: 320, height: 240}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: 0, v_stepping: 0, sizes: null_format_sizes, size_count: 3, bpp: 16, // bpp fourcc: FOURCC('U','Y','V','Y'), // fourcc flags: 0, // flags buffer_types: UNICAP_FLAGS_BUFFER_TYPE_USER | UNICAP_FLAGS_BUFFER_TYPE_SYSTEM, system_buffer_count: THING_SYSTEM_BUFFERS, buffer_size: 320*240*2}, // buffer size { identifier: "RGB32", // name size: { x: 0, y: 0, width: 320, height: 240}, min_size: { x: 0, y: 0, width: 320, height: 240}, max_size: { x: 0, y: 0, width: 640, height: 480}, h_stepping: 0, v_stepping: 0, sizes: null_format_sizes, size_count: 3, bpp: 32, // bpp fourcc: FOURCC('R','G','B','4'), // fourcc flags: 0, // flags buffer_types: UNICAP_FLAGS_BUFFER_TYPE_USER, system_buffer_count: THING_SYSTEM_BUFFERS, buffer_size: 320*240*4}, // buffer size }; char *thingv3_menu_items[] = { "MENU a", "MENU b", "MENU c", "MENU d", }; double value_list_items[] = { 0.0, 1.0, 1.5, 2.0, 3.75, 7.5, }; char *long_name_relations[] = { "frame rate", "thing value_list", }; unicap_property_t null_properties[] = { { identifier: "frame rate", category: "video", unit: "fps", relations: 0, relations_count: 0, { value: 30 }, // default value { range: { min: 1.0, max: 30.0 } }, // range stepping: 1.0, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "thing long name", category: "video", unit: "", relations: long_name_relations, relations_count: sizeof(long_name_relations) / sizeof(char*), { value: 0.5 }, // default value { range: { min: 0.0, max: 1.0 } }, // range stepping: 0.01, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_AUTO | UNICAP_FLAGS_ONE_PUSH | UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "thing m1", category: "video", unit: "", relations: 0, relations_count: 0, { value: 0}, // default value { range: { min: 0, max: 0 } }, // range stepping: 0.1, // stepping type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "thing value_list", category: "video", unit: "", relations: 0, relations_count: 0, { value: 0}, // default value { range: { min: 0, max: 0 } }, // range stepping: 0.1, // stepping type: UNICAP_PROPERTY_TYPE_VALUE_LIST, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "thing a1", category: "video", unit: "", relations: 0, relations_count: 0, { value: 0.5 }, // default value { range: { min: 0.0, max: 1.0 } }, // range stepping: 0.01, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, { identifier: "thing t1", category: "video", unit: "", relations: 0, relations_count: 0, { value: 0.5 }, // default value { range: { min: 0.0, max: 1.0 } }, // range stepping: 0.01, // stepping type: UNICAP_PROPERTY_TYPE_RANGE, flags: 0, flags_mask: UNICAP_FLAGS_MANUAL, property_data: 0, // property data property_data_size: 0, // property data size }, }; struct _null_data_struct { int instance; int device; int format; int capture_running; unicap_property_t *current_properties; struct _unicap_queue *in_queue; int in_queue_lock; struct _unicap_queue *out_queue; int out_queue_lock; struct timeval last_capture_time; unicap_format_t current_format; unsigned char *system_buffers[THING_SYSTEM_BUFFERS]; int current_system_buffer; int frame_rate; }; typedef struct _null_data_struct null_data_t; int g_instance_count = 0; unicap_status_t cpi_register( struct _unicap_cpi *reg_data ) { TRACE( "Register thing.c\n" ); reg_data->cpi_version = 1<<16; reg_data->cpi_capabilities = 0x3ffff; reg_data->cpi_enumerate_devices = cpi_enumerate_devices; reg_data->cpi_open = cpi_open; reg_data->cpi_close = cpi_close; TRACE( "cpi_enumerate_devices: %p\n", cpi_enumerate_devices ); reg_data->cpi_reenumerate_formats = cpi_reenumerate_formats; reg_data->cpi_enumerate_formats = cpi_enumerate_formats; reg_data->cpi_set_format = cpi_set_format; reg_data->cpi_get_format = cpi_get_format; reg_data->cpi_reenumerate_properties = cpi_reenumerate_properties; reg_data->cpi_enumerate_properties = cpi_enumerate_properties; reg_data->cpi_set_property = cpi_set_property; reg_data->cpi_get_property = cpi_get_property; reg_data->cpi_capture_start = cpi_capture_start; reg_data->cpi_capture_stop = cpi_capture_stop; reg_data->cpi_queue_buffer = cpi_queue_buffer; reg_data->cpi_dequeue_buffer = cpi_dequeue_buffer; reg_data->cpi_wait_buffer = cpi_wait_buffer; reg_data->cpi_poll_buffer = cpi_poll_buffer; return STATUS_SUCCESS; } int cpi_open( void **cpi_data, unicap_device_t *device ) { null_data_t *data; TRACE( "open thing.cpi, devcice: %p\n", device ); *cpi_data = calloc( 1, sizeof( struct _null_data_struct ) ); if( !*cpi_data ) { TRACE( "->open STATUS_NO_MEM\n" ); return STATUS_NO_MEM; } data = (null_data_t *)*cpi_data; data->current_properties = malloc( sizeof( null_properties ) ); if( !data->current_properties ) { free( *cpi_data ); return STATUS_NO_MEM; } memcpy( data->current_properties, null_properties, sizeof( null_properties ) ); TRACE( "->open prepare menu items\n" ); // prepare menu items strcpy( data->current_properties[2].menu_item, "MENU c" ); data->current_properties[2].menu.menu_items = thingv3_menu_items; data->current_properties[2].menu.menu_item_count = 4; // prepare value list data->current_properties[3].value = 1.0; data->current_properties[3].value_list.values = value_list_items; data->current_properties[3].value_list.value_count = ( sizeof( value_list_items ) / sizeof( double ) ); TRACE( "->open g_instance_count\n" ); g_instance_count++; data->instance = g_instance_count; data->device = 0; data->format = 0; memcpy( &data->current_format, &null_formats[0], sizeof( unicap_format_t ) ); data->current_format.size.width = 640; data->current_format.size.height = 480; data->capture_running = 0; TRACE( "->open queues\n" ); data->in_queue = malloc( sizeof( struct _unicap_queue ) ); if( !data->in_queue ) { TRACE( "->open NO_MEM\n" ); return STATUS_NO_MEM; } _init_queue( data->in_queue ); TRACE( "->open out_queue\n" ); data->out_queue = malloc( sizeof( struct _unicap_queue ) ); if( !data->out_queue ) { TRACE( "->open NO_MEM\n" ); return STATUS_NO_MEM; } _init_queue( data->out_queue ); data->frame_rate = 30; TRACE( "->open\n" ); return STATUS_SUCCESS; } int cpi_close( void *cpi_data ) { null_data_t *data = cpi_data; TRACE( "close thing\n" ); g_instance_count--; free( data ); return STATUS_SUCCESS; } int cpi_enumerate_devices( unicap_device_t *device, int index ) { TRACE( "thing.cpi: enumerate devices\n" ); if( !device ) { return STATUS_INVALID_PARAMETER; } TRACE( "index: %d\n", index ); if( index >= 0 && index < 3 ) { sprintf( device->identifier, "Thing capture %d", index + 1 ); strcpy( device->model_name, "thing" ); strcpy( device->vendor_name, "Genuine unicap"); } else { return STATUS_NO_DEVICE; } device->model_id = ( index + 1 ) + ( 0x80 << 16 ); device->vendor_id = 0xffff0000; device->flags = UNICAP_CPI_SERIALIZED; strcpy( device->device, "" ) ; // no controlling device return STATUS_SUCCESS; } unicap_status_t cpi_reenumerate_formats( void *cpi_data, int *count ) { int nr_formats = sizeof( null_formats ) / sizeof( unicap_format_t ); TRACE( "thing.cpi: reenumerate formats\n" ); *count = nr_formats; return STATUS_SUCCESS; } int cpi_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ) { int nr_formats = sizeof( null_formats ) / sizeof( unicap_format_t ); null_data_t *data = cpi_data; TRACE( "thing.cpi: enumerate formats\n" ); if( !data || !format ) { return STATUS_INVALID_PARAMETER; } if( ( index >= 0 ) && ( index < nr_formats ) ) { memcpy( format, &null_formats[index], sizeof( unicap_format_t ) ); } else { return STATUS_NO_MATCH; } return STATUS_SUCCESS; } int cpi_set_format( void *cpi_data, unicap_format_t *format ) { int format_index = 0; int nr_formats = sizeof( null_formats ) / sizeof( unicap_format_t ); null_data_t *data = cpi_data; int i; TRACE( "thing.cpi: set_format\n " ); // search for a matching name in the formats list while( ( format_index < nr_formats ) && ( strcmp( format->identifier, null_formats[format_index].identifier ) ) ) { format_index++; } // check if actually found a match or the end of the list was reached if( format_index == nr_formats ) { return STATUS_NO_MATCH; } // remember the format data->format = format_index; format->buffer_size = format->size.width * format->size.height * ( format->bpp / 8 ); memcpy( &data->current_format, &null_formats[format_index], sizeof( unicap_format_t ) ); data->current_format.size.width = format->size.width; data->current_format.size.height = format->size.height; for( i = 0; i < THING_SYSTEM_BUFFERS; i++ ) { if( data->system_buffers[i] ) { free( data->system_buffers[i] ); } data->system_buffers[i] = malloc( format->buffer_size ); } return STATUS_SUCCESS; } unicap_status_t cpi_get_format( void *cpi_data, unicap_format_t *format ) { null_data_t *data = cpi_data; TRACE( "thing.cpi: get_format\n" ); if( data->format == -1 ) { return STATUS_NO_FORMAT; } /* memcpy( format, &null_formats[data->format], sizeof( struct _unicap_format ) ); */ memcpy( format, &data->current_format, sizeof( unicap_format_t ) ); return STATUS_SUCCESS; } unicap_status_t cpi_reenumerate_properties( void *data, int *count ) { int nr_properties = sizeof( null_properties ) / sizeof( struct _unicap_property ); TRACE( "reenumerate properties\n" ); *count = nr_properties; return STATUS_SUCCESS; } unicap_status_t cpi_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ) { int nr_properties = sizeof( null_properties ) / sizeof( struct _unicap_property ); null_data_t *data = cpi_data; TRACE( "thing.cpi: enumerate properties %d\n", index ); if( !data || !property ) { return STATUS_INVALID_PARAMETER; } if( ( index < 0 ) || ( index >= nr_properties ) ) { return STATUS_NO_MATCH; } memcpy( property, &data->current_properties[index], sizeof( unicap_property_t) ); return STATUS_SUCCESS; } unicap_status_t cpi_set_property( void *cpi_data, unicap_property_t *property ) { null_data_t *data = cpi_data; int property_index = 0; int nr_properties = sizeof( null_properties ) / sizeof( unicap_property_t ); TRACE( "thing.cpi: set_property\n" ); if( !data || !property ) { return STATUS_INVALID_PARAMETER; } while( ( property_index < nr_properties ) && ( strcmp( property->identifier, null_properties[property_index].identifier ) ) ) { property_index++; } if( property_index == nr_properties ) { return STATUS_NO_MATCH; } if( !strcmp( property->identifier, "frame rate" ) ) { data->frame_rate = property->value; } else { int relations_count = data->current_properties[property_index].relations_count; char **relations = data->current_properties[property_index].relations; memcpy( &data->current_properties[property_index], property, sizeof( unicap_property_t ) ); data->current_properties[property_index].relations_count = relations_count; data->current_properties[property_index].relations = relations; } return STATUS_SUCCESS; } unicap_status_t cpi_get_property( void *cpi_data, unicap_property_t *property ) { null_data_t *data = cpi_data; int property_index = 0; int nr_properties = sizeof( null_properties ) / sizeof( unicap_property_t ); if( !data || !property ) { return STATUS_INVALID_PARAMETER; } while( ( property_index < nr_properties ) && ( strcmp( property->identifier, null_properties[property_index].identifier ) ) ) { property_index++; } if( property_index == nr_properties ) { return STATUS_NO_MATCH; } memcpy( property, &data->current_properties[property_index], sizeof( unicap_property_t ) ); return STATUS_SUCCESS; } unicap_status_t cpi_capture_start( void *cpi_data ) { null_data_t *data = cpi_data; int old_state = data->capture_running; data->capture_running = 1; gettimeofday( &data->last_capture_time, 0 ); return old_state ? STATUS_CAPTURE_ALREADY_STARTED : STATUS_SUCCESS; } unicap_status_t cpi_capture_stop( void *cpi_data ) { null_data_t *data = cpi_data; int old_state = data->capture_running; data->capture_running = 0; return old_state ? STATUS_CAPTURE_ALREADY_STOPPED : STATUS_SUCCESS; } unicap_status_t cpi_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ) { null_data_t *data = cpi_data; struct _unicap_queue *queue = malloc( sizeof( struct _unicap_queue ) ); TRACE( "Queue buffer\n" ); if( !( data->current_format.buffer_types & (1<type) ) ) { TRACE( "Current format does not support this buffer type\n" ); return STATUS_INVALID_PARAMETER; } if( !( buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) && buffer->buffer_size < ( data->current_format.size.width * data->current_format.size.height * data->current_format.bpp / 8 ) ) { TRACE( "Wrong parameters for buffer: %dx%dx%d => %d\n", data->current_format.size.width, data->current_format.size.height, data->current_format.bpp, buffer->buffer_size ); return STATUS_BUFFER_TOO_SMALL; } if( buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) { buffer->data = data->system_buffers[data->current_system_buffer]; data->current_system_buffer = ( data->current_system_buffer + 1 ) % THING_SYSTEM_BUFFERS; } queue->data = buffer; TRACE( "buffer = %p, size = %d \n", buffer, buffer->buffer_size ); _insert_back_queue( data->in_queue, queue ); return STATUS_SUCCESS; } unicap_status_t cpi_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { null_data_t *data = cpi_data; struct _unicap_queue *entry; TRACE( "Dequeue buffer\n" ); if( data->capture_running ) { return STATUS_IS_RECEIVING; } entry = _get_front_queue( data->in_queue ); if( !entry ) { return STATUS_NO_BUFFERS; } *buffer = entry->data; free( entry ); return STATUS_SUCCESS; } static void fill_buffer( char *buffer, int x, int y, int bpp ) { memset( buffer, 0xff, (bpp/8)*x*y ); switch( bpp ) { case 8: { static char fill = 0x0; fill++; memset( buffer, fill, x*y ); } break; case 16: { static short fill = 0x0000; int i,j; unsigned short *sbuffer = ( unsigned short* )buffer; /* TRACE( "fill: %04x\n", fill ); */ fill = ( fill + 0xf ) % 0xff; for( i = (x/3); i < ((x*2)/3); i++ ) { for( j = (y/3); j < ((y*2)/3); j++ ) { sbuffer[ (j*x)+i ] = fill; } } } break; case 32: { static long fill = 0x00000000; int i, j; unsigned long *lbuffer = ( unsigned long* )buffer; fill = ( fill + 0x0a0a0aff ); TRACE( "fill = %08x\n", fill ); for( i = (x/3 ); i < ( ( x * 2 ) / 3 ); i++ ) { for( j = ( y/3 ); j < ( ( y*2 ) / 3 ); j++ ) { lbuffer[ (j*x)+i ] = fill; } } } break; default: { } break; } } unicap_status_t cpi_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { null_data_t *data = cpi_data; static char fillbyte = 0; if( data->in_queue->next ) { struct _unicap_queue *entry; int offset = 0; int x; int y; int width = null_formats[data->format].size.width; struct timeval ctime; long usec; gettimeofday( &ctime, 0 ); ctime.tv_sec -= data->last_capture_time.tv_sec; if( ctime.tv_usec < data->last_capture_time.tv_usec ) { ctime.tv_sec--; ctime.tv_usec += 1000000; } ctime.tv_usec -= data->last_capture_time.tv_usec; usec = ctime.tv_usec + ( ctime.tv_sec * 1000000 ); gettimeofday( &data->last_capture_time, 0 ); if( usec < (1000000/data->frame_rate) ) { usleep( usec ); } _move_to_queue( data->in_queue, data->out_queue ); entry = _get_front_queue( data->out_queue ); *buffer = entry->data; memcpy( &(*buffer)->format, &data->current_format, sizeof( unicap_format_t ) ); fill_buffer( (*buffer)->data, (*buffer)->format.size.width, (*buffer)->format.size.height, (*buffer)->format.bpp ); free( entry ); return STATUS_SUCCESS; } return STATUS_FAILURE; } unicap_status_t cpi_poll_buffer( void *cpi_data, int *count ) { null_data_t *data = cpi_data; *count = _queue_get_size( data->in_queue ); return STATUS_SUCCESS; } libunicap/cpi/thing/thing.h0000644000175000017500000000414513164711411016427 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NULL_H__ #define __NULL_H__ int cpi_enumerate_devices( unicap_device_t *device, int index ); int cpi_open( void **cpi_data, unicap_device_t *device ); int cpi_close( void *cpi_data ); unicap_status_t cpi_reenumerate_formats( void *cpi_data, int *count ); int cpi_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ); int cpi_set_format( void *cpi_data, unicap_format_t *format ); unicap_status_t cpi_get_format( void *cpi_data, unicap_format_t *format ); unicap_status_t cpi_reenumerate_properties( void *cpi_data, int *count ); unicap_status_t cpi_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ); unicap_status_t cpi_set_property( void *cpi_data, unicap_property_t *property ); unicap_status_t cpi_get_property( void *cpi_data, unicap_property_t *property ); unicap_status_t cpi_capture_start( void *cpi_data ); unicap_status_t cpi_capture_stop( void *cpi_data ); unicap_status_t cpi_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ); unicap_status_t cpi_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); unicap_status_t cpi_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); unicap_status_t cpi_poll_buffer( void *cpi_data, int *count ); #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #endif//__NULL_H__ libunicap/cpi/TODO0000644000175000017500000000004513164711411014517 0ustar zmoelnigzmoelnigtest: queue.c ( _insert_front_queue )libunicap/cpi/include/0000755000175000017500000000000013164711411015453 5ustar zmoelnigzmoelniglibunicap/cpi/include/video1394.h0000644000175000017500000000372313164711411017260 0ustar zmoelnigzmoelnig/* * video1394.h - driver for OHCI 1394 boards * Copyright (C)1999,2000 Sebastien Rougeaux * Peter Schlaile * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _VIDEO_1394_H #define _VIDEO_1394_H #include "ieee1394-ioctl.h" #define VIDEO1394_DRIVER_NAME "video1394" #define VIDEO1394_MAX_SIZE 0x4000000 enum { VIDEO1394_BUFFER_FREE = 0, VIDEO1394_BUFFER_QUEUED, VIDEO1394_BUFFER_READY }; #define VIDEO1394_SYNC_FRAMES 0x00000001 #define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002 #define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004 struct video1394_mmap { int channel; /* -1 to find an open channel in LISTEN/TALK */ unsigned int sync_tag; unsigned int nb_buffers; unsigned int buf_size; unsigned int packet_size; /* For VARIABLE_PACKET_SIZE: Maximum packet size */ unsigned int fps; unsigned int syt_offset; unsigned int flags; }; /* For TALK_QUEUE_BUFFER with VIDEO1394_VARIABLE_PACKET_SIZE use */ struct video1394_queue_variable { unsigned int channel; unsigned int buffer; unsigned int* packet_sizes; /* Buffer of size: buf_size / packet_size */ }; struct video1394_wait { unsigned int channel; unsigned int buffer; struct timeval filltime; /* time of buffer full */ }; #endif libunicap/cpi/include/Makefile.am0000644000175000017500000000031513164711411017506 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in # headers to be installed # pkginclude_HEADERS = EXTRA_DIST = 1394util.h ieee1394-ioctl.h unicap_cpi.h unicap_cpi_std_struct.h video1394.h video1394_2_4.h static_cpi.h libunicap/cpi/include/unicap_cpi.h0000644000175000017500000001123713164711411017742 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UNICAP_CPI_H__ #define __UNICAP_CPI_H__ #include "unicap.h" #include "unicap_status.h" int unicap_cache_add( char *key, void *value ); void* unicap_cache_get( char *key ); void unicap_cache_unref( char *key ); typedef struct _unicap_cpi * unicap_cpi_t; typedef unicap_status_t (*cpi_register_t) ( unicap_cpi_t ); typedef unicap_status_t (*cpi_enumerate_devices_t) (unicap_device_t *device, int index); typedef unicap_status_t (*cpi_open_t) (void **, unicap_device_t *device ); typedef unicap_status_t (*cpi_close_t) (void *); typedef unicap_status_t (*cpi_reenumerate_formats_t) (void *, int *count ); typedef unicap_status_t (*cpi_enumerate_formats_t) (void *, unicap_format_t *format, int index); typedef unicap_status_t (*cpi_set_format_t) (void *, unicap_format_t *format); typedef unicap_status_t (*cpi_get_format_t) (void *, unicap_format_t *format); typedef unicap_status_t (*cpi_reenumerate_properties_t)(void *, int *count ); typedef unicap_status_t (*cpi_enumerate_properties_t) (void *, unicap_property_t *property, int index); typedef unicap_status_t (*cpi_set_property_t) (void *, unicap_property_t *property); typedef unicap_status_t (*cpi_get_property_t) (void *, unicap_property_t *property); typedef unicap_status_t (*cpi_capture_start_t) (void *); typedef unicap_status_t (*cpi_capture_stop_t) (void *); typedef unicap_status_t (*cpi_queue_buffer_t) (void *, unicap_data_buffer_t *buffer); typedef unicap_status_t (*cpi_dequeue_buffer_t)(void *, unicap_data_buffer_t **buffer); typedef unicap_status_t (*cpi_wait_buffer_t) (void *, unicap_data_buffer_t **buffer); typedef unicap_status_t (*cpi_poll_buffer_t) (void *, int *count); typedef void (*unicap_event_callback_t) (unicap_handle_t handle, unicap_event_t event, ... ); typedef unicap_status_t (*cpi_set_event_notify_t ) ( void *, unicap_event_callback_t func, unicap_handle_t handle ); #define UNICAP_CPI_SERIALIZED 0x1 #define UNICAP_CPI_REMOTE 0x2 #define CPI_CAP_ENUMERATE_DEVICES ( 1<<0 ) #define CPI_CAP_OPEN ( 1<<1 ) #define CPI_CAP_CLOSE ( 1<<2 ) #define CPI_CAP_REENUMERATE_FORMATS ( 1<<3 ) #define CPI_CAP_ENUMERATE_FORMATS ( 1<<4 ) #define CPI_CAP_SET_FORMAT ( 1<<5 ) #define CPI_CAP_GET_FORMAT ( 1<<6 ) #define CPI_CAP_REENUMERATE_PROPERTIES ( 1<<7 ) #define CPI_CAP_ENUMERATE_PROPERTIES ( 1<<8 ) #define CPI_CAP_SET_PROPERTY ( 1<<9 ) #define CPI_CAP_GET_PROPERTY ( 1<<10 ) #define CPI_CAP_CAPTURE_START ( 1<<11 ) #define CPI_CAP_CAPTURE_STOP ( 1<<12 ) #define CPI_CAP_QUEUE_BUFFER ( 1<<13 ) #define CPI_CAP_DEQUEUE_BUFFER ( 1<<14 ) #define CPI_CAP_WAIT_BUFFER ( 1<<15 ) #define CPI_CAP_POLL_BUFFER ( 1<<16 ) #define CPI_CAP_SET_EVENT_NOTIFY ( 1<<17 ) struct _unicap_cpi { unsigned int cpi_version; u_int64_t cpi_capabilities; u_int64_t cpi_flags; cpi_register_t cpi_register; cpi_enumerate_devices_t cpi_enumerate_devices; cpi_open_t cpi_open; cpi_close_t cpi_close; cpi_reenumerate_formats_t cpi_reenumerate_formats; cpi_enumerate_formats_t cpi_enumerate_formats; cpi_set_format_t cpi_set_format; cpi_get_format_t cpi_get_format; cpi_reenumerate_properties_t cpi_reenumerate_properties; cpi_enumerate_properties_t cpi_enumerate_properties; cpi_set_property_t cpi_set_property; cpi_get_property_t cpi_get_property; cpi_capture_start_t cpi_capture_start; cpi_capture_stop_t cpi_capture_stop; cpi_queue_buffer_t cpi_queue_buffer; cpi_dequeue_buffer_t cpi_dequeue_buffer; cpi_wait_buffer_t cpi_wait_buffer; cpi_poll_buffer_t cpi_poll_buffer; cpi_set_event_notify_t cpi_set_event_notify; void *reserved[43]; }; #define CPI_VERSION_HI(x) (x>>16) #endif//__UNICAP_CPI_H__ libunicap/cpi/include/unicap_cpi_std_struct.h0000644000175000017500000000213613164711411022216 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UNICAP_CPI_STD_STRUCT_H__ #define __UNICAP_CPI_STD_STRUCT_H__ #include #define S_PPTY_INFO_VIDEO "video", "", 0, 0 #define S_PPTY_INFO_LENS "lens", "", 0, 0 #define S_PPTY_INFO_MISC "misc", "", 0, 0 #define S_PPTY_INFO_DEVICE_STATE "device state", "", 0, 0 #define S_PPTY_INFO_TRIGGER "trigger", "", 0, 0 #endif libunicap/cpi/include/1394util.h0000644000175000017500000000443713164711411017132 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UTIL_H__ #define __UTIL_H__ #include #include #ifdef RAW1394_1_1_API #include #include #else #include #include #endif int cooked1394_read( raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *buffer ); int cooked1394_write( raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *data); unsigned long long get_guid( raw1394handle_t handle, int phyID ); unsigned int get_unit_spec_ID( raw1394handle_t handle, int phyID ); unsigned int get_unit_sw_version( raw1394handle_t handle, int phyID ); int _1394util_find_free_channel( raw1394handle_t raw1394handle ); int _1394util_free_channel( raw1394handle_t raw1394handle, int channel ); int _1394util_allocate_channel( raw1394handle_t raw1394handle, int channel ); int _1394util_allocate_bandwidth( raw1394handle_t raw1394handle, int bandwidth ); int _1394util_free_bandwidth( raw1394handle_t raw1394handle, int bandwidth ); int _1394util_get_available_bandwidth( raw1394handle_t raw1394handle ); unicap_status_t _1394util_send_fcp_command_ext( raw1394handle_t raw1394handle, nodeid_t nodeid, unsigned long long fcp_command, unsigned long *sync_bit_store, void *data, size_t data_length, unsigned long *response ); unsigned long bswap( unsigned long v ); quadlet_t bitswap( quadlet_t value ); #endif //__UTIL_H__ libunicap/cpi/include/video1394_2_4.h0000644000175000017500000000446613164711411017731 0ustar zmoelnigzmoelnig/* * video1394.h - driver for OHCI 1394 boards * Copyright (C)1999,2000 Sebastien Rougeaux * Peter Schlaile * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _VIDEO_1394_H #define _VIDEO_1394_H #include "ieee1394-ioctl.h" #define VIDEO1394_DRIVER_NAME "video1394" #define VIDEO1394_MAX_SIZE 0x4000000 enum { VIDEO1394_BUFFER_FREE = 0, VIDEO1394_BUFFER_QUEUED, VIDEO1394_BUFFER_READY }; enum { VIDEO1394_LISTEN_CHANNEL = 0, VIDEO1394_UNLISTEN_CHANNEL, VIDEO1394_LISTEN_QUEUE_BUFFER, VIDEO1394_LISTEN_WAIT_BUFFER, // wait until buffer is ready VIDEO1394_TALK_CHANNEL, VIDEO1394_UNTALK_CHANNEL, VIDEO1394_TALK_QUEUE_BUFFER, VIDEO1394_TALK_WAIT_BUFFER, VIDEO1394_LISTEN_POLL_BUFFER // return immediately with -EINTR if not ready }; #define VIDEO1394_SYNC_FRAMES 0x00000001 #define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002 #define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004 struct video1394_mmap { int channel; /* -1 to find an open channel in LISTEN/TALK */ unsigned int sync_tag; unsigned int nb_buffers; unsigned int buf_size; unsigned int packet_size; /* For VARIABLE_PACKET_SIZE: Maximum packet size */ unsigned int fps; unsigned int syt_offset; unsigned int flags; }; /* For TALK_QUEUE_BUFFER with VIDEO1394_VARIABLE_PACKET_SIZE use */ struct video1394_queue_variable { unsigned int channel; unsigned int buffer; unsigned int* packet_sizes; /* Buffer of size: buf_size / packet_size */ }; struct video1394_wait { unsigned int channel; unsigned int buffer; struct timeval filltime; /* time of buffer full */ }; #endif libunicap/cpi/include/ieee1394-ioctl.h0000644000175000017500000000725713164711411020177 0ustar zmoelnigzmoelnig/* Base file for all ieee1394 ioctl's. Linux-1394 has allocated base '#' * with a range of 0x00-0x3f. */ #ifndef __IEEE1394_IOCTL_H #define __IEEE1394_IOCTL_H #include #include /* AMDTP Gets 6 */ #define AMDTP_IOC_CHANNEL _IOW('#', 0x00, struct amdtp_ioctl) #define AMDTP_IOC_PLUG _IOW('#', 0x01, struct amdtp_ioctl) #define AMDTP_IOC_PING _IOW('#', 0x02, struct amdtp_ioctl) #define AMDTP_IOC_ZAP _IO ('#', 0x03) /* DV1394 Gets 10 */ /* Get the driver ready to transmit video. pass a struct dv1394_init* as * the parameter (see below), or NULL to get default parameters */ #define DV1394_IOC_INIT _IOW('#', 0x06, struct dv1394_init) /* Stop transmitting video and free the ringbuffer */ #define DV1394_IOC_SHUTDOWN _IO ('#', 0x07) /* Submit N new frames to be transmitted, where the index of the first new * frame is first_clear_buffer, and the index of the last new frame is * (first_clear_buffer + N) % n_frames */ #define DV1394_IOC_SUBMIT_FRAMES _IO ('#', 0x08) /* Block until N buffers are clear (pass N as the parameter) Because we * re-transmit the last frame on underrun, there will at most be n_frames * - 1 clear frames at any time */ #define DV1394_IOC_WAIT_FRAMES _IO ('#', 0x09) /* Capture new frames that have been received, where the index of the * first new frame is first_clear_buffer, and the index of the last new * frame is (first_clear_buffer + N) % n_frames */ #define DV1394_IOC_RECEIVE_FRAMES _IO ('#', 0x0a) /* Tell card to start receiving DMA */ #define DV1394_IOC_START_RECEIVE _IO ('#', 0x0b) /* Pass a struct dv1394_status* as the parameter */ #define DV1394_IOC_GET_STATUS _IOR('#', 0x0c, struct dv1394_status) /* Video1394 Gets 10 */ #define VIDEO1394_IOC_LISTEN_CHANNEL \ _IOWR('#', 0x10, struct video1394_mmap) #define VIDEO1394_IOC_UNLISTEN_CHANNEL \ _IOW ('#', 0x11, int) #define VIDEO1394_IOC_LISTEN_QUEUE_BUFFER \ _IOW ('#', 0x12, struct video1394_wait) #define VIDEO1394_IOC_LISTEN_WAIT_BUFFER \ _IOWR('#', 0x13, struct video1394_wait) #define VIDEO1394_IOC_TALK_CHANNEL \ _IOWR('#', 0x14, struct video1394_mmap) #define VIDEO1394_IOC_UNTALK_CHANNEL \ _IOW ('#', 0x15, int) #define VIDEO1394_IOC_TALK_QUEUE_BUFFER \ _IOW ('#', 0x16, sizeof (struct video1394_wait) + \ sizeof (struct video1394_queue_variable)) #define VIDEO1394_IOC_TALK_WAIT_BUFFER \ _IOW ('#', 0x17, struct video1394_wait) #define VIDEO1394_IOC_LISTEN_POLL_BUFFER \ _IOWR('#', 0x18, struct video1394_wait) /* Raw1394's ISO interface */ #define RAW1394_IOC_ISO_XMIT_INIT \ _IOW ('#', 0x1a, struct raw1394_iso_status) #define RAW1394_IOC_ISO_RECV_INIT \ _IOWR('#', 0x1b, struct raw1394_iso_status) #define RAW1394_IOC_ISO_RECV_START \ _IOC (_IOC_WRITE, '#', 0x1c, sizeof(int) * 3) #define RAW1394_IOC_ISO_XMIT_START \ _IOC (_IOC_WRITE, '#', 0x1d, sizeof(int) * 2) #define RAW1394_IOC_ISO_XMIT_RECV_STOP \ _IO ('#', 0x1e) #define RAW1394_IOC_ISO_GET_STATUS \ _IOR ('#', 0x1f, struct raw1394_iso_status) #define RAW1394_IOC_ISO_SHUTDOWN \ _IO ('#', 0x20) #define RAW1394_IOC_ISO_QUEUE_ACTIVITY \ _IO ('#', 0x21) #define RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL \ _IOW ('#', 0x22, unsigned char) #define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL \ _IOW ('#', 0x23, unsigned char) #define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK \ _IOW ('#', 0x24, __u64) #define RAW1394_IOC_ISO_RECV_PACKETS \ _IOW ('#', 0x25, struct raw1394_iso_packets) #define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS \ _IOW ('#', 0x26, unsigned int) #define RAW1394_IOC_ISO_XMIT_PACKETS \ _IOW ('#', 0x27, struct raw1394_iso_packets) #define RAW1394_IOC_ISO_XMIT_SYNC \ _IO ('#', 0x28) #define RAW1394_IOC_ISO_RECV_FLUSH \ _IO ('#', 0x29) #endif /* __IEEE1394_IOCTL_H */ libunicap/cpi/include/static_cpi.h0000644000175000017500000000125313164711411017747 0ustar zmoelnigzmoelnig/* ** static_cpi.h ** ** Made by Arne Caspari ** Login ** ** Started on Wed Jun 13 07:56:40 2007 Arne Caspari ** Last update Wed Jun 13 07:56:40 2007 Arne Caspari */ #ifndef STATIC_CPI_H_ # define STATIC_CPI_H_ #include "config.h" #include "unicap_cpi.h" enum unicap_static_cpi_enum { UNICAP_STATIC_CPI_INVALID = -1, #if BUILD_DCAM UNICAP_STATIC_CPI_DCAM, #endif #if BUILD_VID21394 UNICAP_STATIC_CPI_VID21394, #endif #if BUILD_V4L UNICAP_STATIC_CPI_V4L, #endif #if BUILD_V4L2 UNICAP_STATIC_CPI_V4L2, #endif UNICAP_STATIC_CPI_COUNT }; struct _unicap_cpi *static_cpis_s[UNICAP_STATIC_CPI_COUNT+1]; #endif /* !STATIC_CPI_H_ */ libunicap/cpi/v4l2cpi/0000755000175000017500000000000013164711411015313 5ustar zmoelnigzmoelniglibunicap/cpi/v4l2cpi/udev.h0000644000175000017500000000154013164711411016427 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2011 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UDEV_H__ #define __UDEV_H__ char *v4l2cpi_udev_get_serial (const char* devfile); #endif//__UDEV_H__ libunicap/cpi/v4l2cpi/v4l2.c0000644000175000017500000017531213164711411016257 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define N_(x) x #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "v4l2.h" #include "buffermanager.h" #include "tisuvccam.h" #include "tiseuvccam.h" #include "udev.h" #if USE_LIBV4L #include #endif #if V4L2_DEBUG #define DEBUG #endif #include "debug.h" #define V4L2_VIDEO_IN_PPTY_NAME N_("video source") #define V4L2_VIDEO_NORM_PPTY_NAME N_("video norm") #define V4L2_VIDEO_FRAMERATE_PPTY_NAME N_("frame rate") #ifndef V4L2_CTRL_CLASS_CAMERA #define V4L2_CTRL_CLASS_CAMERA 0x009A0000 /* Camera class controls */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) #endif #if USE_LIBV4L #define OPEN v4l2_open #define CLOSE v4l2_close #define IOCTL v4l2_ioctl #define MMAP v4l2_mmap #define MUNMAP v4l2_munmap #else #define OPEN open #define CLOSE close #define IOCTL ioctl #define MMAP mmap #define MUNMAP munmap #endif struct prop_category { char *property_id; char *category; }; struct fourcc_bpp { __u32 fourcc; int bpp; }; struct prop_category category_list[] = { { N_("shutter"), N_("exposure") }, { N_("gain"), "exposure" }, { N_("brightness"), "exposure" }, { N_("white balance red component"), N_("color") }, { N_("white balance blue component"), "color" }, { N_("white balance component, auto"), "color" }, { N_("white balance temperature"), "color" }, { N_("saturation"), "color" }, }; static struct v4l2_uc_compat v4l2_uc_compat_list[] = { { driver: "uvcvideo", probe_func: tisuvccam_probe, count_ext_property_func: tisuvccam_count_ext_property, enumerate_property_func: tisuvccam_enumerate_properties, override_property_func: tisuvccam_override_property, set_property_func: tisuvccam_set_property, get_property_func: tisuvccam_get_property, fmt_get_func: tisuvccam_fmt_get, override_framesize_func: NULL, tov4l2format_func: NULL, }, /* { */ /* driver: "uvcvideo", */ /* probe_func: tiseuvccam_probe, */ /* count_ext_property_func: tiseuvccam_count_ext_property, */ /* enumerate_property_func: tiseuvccam_enumerate_properties, */ /* override_property_func: tiseuvccam_override_property, */ /* set_property_func: tiseuvccam_set_property, */ /* get_property_func: tiseuvccam_get_property, */ /* fmt_get_func: tiseuvccam_fmt_get, */ /* #ifdef VIDIOC_ENUM_FRAMESIZES */ /* override_framesize_func: tiseuvccam_override_framesize, */ /* #else */ /* override_framesize_func: NULL, */ /* #endif */ /* tov4l2format_func: tiseuvccam_tov4l2format, */ /* }, */ }; static struct fourcc_bpp fourcc_bpp_map[] = { { V4L2_PIX_FMT_GREY, 8 }, { V4L2_PIX_FMT_YUYV, 16 }, { V4L2_PIX_FMT_UYVY, 16 }, { V4L2_PIX_FMT_Y41P, 12 }, { V4L2_PIX_FMT_YVU420, 12 }, { V4L2_PIX_FMT_YUV420, 12 }, { V4L2_PIX_FMT_YVU410, 9 }, { V4L2_PIX_FMT_YUV410, 9 }, { V4L2_PIX_FMT_YUV422P, 16 }, { V4L2_PIX_FMT_YUV411P, 12 }, { V4L2_PIX_FMT_NV12, 12 }, { V4L2_PIX_FMT_NV21, 12 }, { V4L2_PIX_FMT_YYUV, 16 }, { V4L2_PIX_FMT_HI240, 8 }, { V4L2_PIX_FMT_RGB332, 8 }, { V4L2_PIX_FMT_RGB555, 16 }, { V4L2_PIX_FMT_RGB565, 16 }, { V4L2_PIX_FMT_RGB555X, 16 }, { V4L2_PIX_FMT_RGB565X, 16 }, { V4L2_PIX_FMT_BGR24, 24 }, { V4L2_PIX_FMT_RGB24, 24 }, { V4L2_PIX_FMT_BGR32, 32 }, { V4L2_PIX_FMT_RGB32, 32 }, { FOURCC( 'Y', '8', '0', '0' ), 8 }, { FOURCC( 'B', 'Y', '8', ' ' ), 8 }, { FOURCC( 'B', 'A', '8', '1' ), 8 }, }; struct size_map_s { char *card_name; unicap_rect_t *sizes; int size_count; }; static unicap_rect_t try_sizes[] = { { 0,0, 160, 120 }, { 0,0, 176, 144 }, { 0,0, 320, 240 }, { 0,0, 384, 288 }, { 0,0, 640, 480 }, { 0,0, 720, 480 }, { 0,0, 720, 576 }, { 0,0, 768, 576 }, { 0,0, 800, 600 }, { 0,0, 1024, 768 }, { 0,0, 1280, 960 }, }; static unicap_rect_t webcam_sizes[] = { { 0,0, 160, 120 }, { 0,0, 320, 240 }, { 0,0, 352, 288 }, { 0,0, 640, 480 }, { 0,0, 748, 480 }, }; static unicap_rect_t dxx41_sizes[] = { { 0,0, 1280, 960 }, }; static struct size_map_s format_size_map[] = { { N_("STK-1135 USB2 Camera Controller"), webcam_sizes, sizeof( webcam_sizes ) / sizeof( unicap_rect_t ) }, { N_("DFx 41"), dxx41_sizes, sizeof( dxx41_sizes ) / sizeof( unicap_rect_t ) }, }; static unicap_status_t v4l2_enum_frameintervals( v4l2_handle_t handle, unicap_property_t *property ); static unicap_status_t v4l2_enumerate_devices( unicap_device_t *device, int index ); static unicap_status_t v4l2_cpi_open( void **cpi_data, unicap_device_t *device ); static unicap_status_t v4l2_cpi_close( void *cpi_data ); static unicap_status_t v4l2_reenumerate_formats( void *cpi_data, int *_pcount ); static unicap_status_t v4l2_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ); static unicap_status_t v4l2_set_format( void *cpi_data, unicap_format_t *format ); static unicap_status_t v4l2_get_format( void *cpi_data, unicap_format_t *format ); static unicap_status_t v4l2_reenumerate_properties( void *cpi_data, int *_pcount ); static unicap_status_t v4l2_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ); static unicap_status_t v4l2_set_property( void *cpi_data, unicap_property_t *property ); static unicap_status_t v4l2_get_property( void *cpi_data, unicap_property_t *property ); static unicap_status_t v4l2_capture_start( void *cpi_data ); static unicap_status_t v4l2_capture_stop( void *cpi_data ); static unicap_status_t v4l2_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ); static unicap_status_t v4l2_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); static unicap_status_t v4l2_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); static unicap_status_t v4l2_poll_buffer( void *cpi_data, int *count ); static unicap_status_t v4l2_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ); static unicap_status_t queue_buffer( v4l2_handle_t handle, unicap_data_buffer_t *buffer ); static unicap_status_t queue_system_buffers( v4l2_handle_t handle ); static void v4l2_capture_thread( v4l2_handle_t handle ); static struct _unicap_cpi cpi_s = { cpi_version: 1<<16, cpi_capabilities: 0x3ffff, cpi_enumerate_devices: v4l2_enumerate_devices, cpi_open: v4l2_cpi_open, cpi_close: v4l2_cpi_close, cpi_reenumerate_formats: v4l2_reenumerate_formats, cpi_enumerate_formats: v4l2_enumerate_formats, cpi_set_format: v4l2_set_format, cpi_get_format: v4l2_get_format, cpi_reenumerate_properties: v4l2_reenumerate_properties, cpi_enumerate_properties: v4l2_enumerate_properties, cpi_set_property: v4l2_set_property, cpi_get_property: v4l2_get_property, cpi_capture_start: v4l2_capture_start, cpi_capture_stop: v4l2_capture_stop, cpi_queue_buffer: v4l2_queue_buffer, cpi_dequeue_buffer: v4l2_dequeue_buffer, cpi_wait_buffer: v4l2_wait_buffer, cpi_poll_buffer: v4l2_poll_buffer, cpi_set_event_notify: v4l2_set_event_notify, }; #if ENABLE_STATIC_CPI void unicap_v4l2_register_static_cpi( struct _unicap_cpi **cpi ) { *cpi = &cpi_s; } #else unicap_status_t cpi_register( struct _unicap_cpi *reg_data ) { memcpy( reg_data, &cpi_s, sizeof( struct _unicap_cpi ) ); return STATUS_SUCCESS; } #endif//ENABLE_STATIC_CPI static unicap_status_t get_current_format( v4l2_handle_t handle, unicap_format_t *format ) { struct v4l2_cropcap v4l2_crop; struct v4l2_format v4l2_fmt; struct v4l2_fmtdesc v4l2_fmtdesc; int i; int index = -1; unsigned int pixelformat; v4l2_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( IOCTL( handle->fd, VIDIOC_CROPCAP, &v4l2_crop ) < 0 ) { v4l2_crop.defrect.width = v4l2_crop.bounds.width = 640; v4l2_crop.defrect.height = v4l2_crop.bounds.height = 480; } v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( IOCTL( handle->fd, VIDIOC_G_FMT, &v4l2_fmt ) ) { TRACE( "VIDIOC_G_FMT ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } pixelformat = v4l2_fmt.fmt.pix.pixelformat; if( handle->compat ) { memset( &v4l2_fmtdesc, 0x0, sizeof( v4l2_fmtdesc ) ); v4l2_fmtdesc.pixelformat = v4l2_fmt.fmt.pix.pixelformat; handle->compat->fmt_get_func( &v4l2_fmtdesc, &v4l2_crop, NULL, &pixelformat, NULL ); } for( i = 0; i < handle->format_count; i++ ) { if( pixelformat == handle->unicap_formats[ i ].fourcc ) { index = i; break; } } if( index == -1 ) { TRACE( "v4l2 get format: format not in the list of currently known formats; pixelformat = %08x\n", pixelformat ); return STATUS_FAILURE; } unicap_copy_format( format, &handle->unicap_formats[index] ); return STATUS_SUCCESS; } static int file_filter( const struct dirent *a ) { int match = 0; // match: 'videoXY' where X = {0..9} and Y = {0..9} if( !strncmp( a->d_name, "video", 5 ) ) { if( strlen( a->d_name ) > 5 ) { if( ( a->d_name[5] >= '0' ) && ( a->d_name[5] <= '9' ) ) // match // the 'X' { match = 1; } if( strlen( a->d_name ) > 6 ) { match = 0; if( ( a->d_name[6] >= '0' ) && ( a->d_name[6] <= '9' ) ) { match = 1; } } if( strlen( a->d_name ) > 7 ) { match = 0; } } } return match; } static unicap_status_t v4l2_enumerate_devices( unicap_device_t *device, int index ) { int fd; struct v4l2_capability v4l2caps; struct dirent **namelist; int n; int found = -1; char devname[512]; char *serial; TRACE( "v4l2_enumerate_devices[%d]\n", index ); n = scandir( "/dev", &namelist, file_filter, alphasort ); if( n < 0 ) { TRACE( "Failed to scan directory '/dev' \n" ); return STATUS_NO_DEVICE; } while( ( found != index ) && n-- ) { sprintf( devname, "/dev/%s", namelist[n]->d_name ); /* free( namelist[n]->d_name ); */ TRACE( "v4l2: open %s\n", devname ); if( ( fd = open( devname, O_RDONLY | O_NONBLOCK ) ) == -1 ) { TRACE( "v4l2_cpi: open(%s): %s\n", devname, strerror( errno ) ); continue; } #if USE_LIBV4L v4l2_fd_open( fd, V4L2_ENABLE_ENUM_FMT_EMULATION ); #endif if( IOCTL( fd, VIDIOC_QUERYCAP, &v4l2caps ) < 0 ) { TRACE( "ioctl failed\n" ); close( fd ); continue; } if( !(v4l2caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) ) { // v4l version one device CLOSE( fd ); continue; } found++; CLOSE( fd ); } /* free( namelist ); */ if( found != index ) { return STATUS_NO_DEVICE; } TRACE ("Bus: %s\n", v4l2caps.bus_info); serial = v4l2cpi_udev_get_serial (devname); if (serial){ sprintf( device->identifier, "%s %s", v4l2caps.card, serial ); device->model_id = atoll (serial); free (serial); } else { sprintf( device->identifier, "%s (%s)", v4l2caps.card, devname ); device->model_id = 0x1; } strcpy( device->model_name, (char*)v4l2caps.card ); strcpy( device->vendor_name, ""); device->vendor_id = 0xffff0000; device->flags = UNICAP_CPI_SERIALIZED; strcpy( device->device, devname ) ; return STATUS_SUCCESS; } static unicap_status_t v4l2_cpi_open( void **cpi_data, unicap_device_t *device ) { v4l2_handle_t handle = NULL; struct v4l2_capability v4l2caps; char identifier[128]; char *serial; int i; TRACE( "v4l2_cpi_open\n" ); *cpi_data = malloc( sizeof( struct _v4l2_handle ) ); memset( *cpi_data, 0x0, sizeof( struct _v4l2_handle ) ); handle = (v4l2_handle_t) *cpi_data; if( sem_init( &handle->sema, 0, 1 ) ) { TRACE( "sem_init failed!\n" ); free( handle ); return STATUS_FAILURE; } handle->removed = 0; handle->io_method = CPI_V4L2_IO_METHOD_MMAP; handle->buffer_count = V4L2_NUM_BUFFERS; handle->fd = open( device->device, O_RDWR ); if( handle->fd == -1 ) { TRACE( "v4l2 open failed\n" ); free( handle ); return STATUS_FAILURE; } #if USE_LIBV4L v4l2_fd_open( handle->fd, V4L2_ENABLE_ENUM_FMT_EMULATION ); #endif for( i = 0; i < V4L2_MAX_VIDEO_INPUTS; i++ ) { handle->video_inputs[i] = malloc( 32 ); } for( i = 0; i < V4L2_MAX_VIDEO_NORMS; i++ ) { handle->video_norms[i] = malloc( 32 ); } memset( &v4l2caps, 0x0, sizeof( v4l2caps ) ); if( IOCTL( handle->fd, VIDIOC_QUERYCAP, &v4l2caps ) < 0 ) { TRACE( "ioctl failed\n" ); for( i = 0; i < V4L2_MAX_VIDEO_INPUTS; i++ ) { free( handle->video_inputs[i] ); } for( i = 0; i < V4L2_MAX_VIDEO_NORMS; i++ ) { free( handle->video_norms[i] ); } CLOSE( handle->fd ); free( handle ); return STATUS_FAILURE; } serial = v4l2cpi_udev_get_serial (device->device); if (serial){ sprintf( identifier, "%s %s", v4l2caps.card, serial ); free (serial); } else { sprintf( identifier, "%s (%s)", v4l2caps.card, device->device ); } if( strcmp( identifier, device->identifier ) ) { for( i = 0; i < V4L2_MAX_VIDEO_INPUTS; i++ ) { free( handle->video_inputs[i] ); } for( i = 0; i < V4L2_MAX_VIDEO_NORMS; i++ ) { free( handle->video_norms[i] ); } CLOSE( handle->fd ); free( handle ); return STATUS_NO_MATCH; } strcpy( handle->card_name, (char*) v4l2caps.card ); for( i = 0; i < ( sizeof( v4l2_uc_compat_list ) / sizeof( struct v4l2_uc_compat ) ); i++ ) { if( !strcmp( (char*)v4l2_uc_compat_list[i].driver, (char*)v4l2caps.driver ) ) { if( v4l2_uc_compat_list[i].probe_func( handle, device->device ) ) { handle->compat = &v4l2_uc_compat_list[i]; break; } } } v4l2_reenumerate_formats( handle, NULL ); get_current_format( handle, &handle->current_format ); v4l2_reenumerate_properties( handle, NULL ); handle->in_queue = ucutil_queue_new(); handle->out_queue = ucutil_queue_new(); return STATUS_SUCCESS; } static unicap_status_t v4l2_cpi_close( void *cpi_data ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; TRACE( "v4l2_cpi_close\n" ); if( handle->capture_running ) { v4l2_capture_stop( cpi_data ); } if( handle->unicap_formats ) { int i; if( handle->sizes_allocated ) { for( i = 0; i < handle->format_count; i++ ) { if( handle->unicap_formats[i].sizes ) { free( handle->unicap_formats[i].sizes ); } } } free( handle->unicap_formats ); handle->unicap_formats = 0; } if( handle->unicap_properties ) { free( handle->unicap_properties ); handle->unicap_properties = 0; } if( handle->control_ids ) { free( handle->control_ids ); handle->control_ids = 0; } if( handle->unicap_handle ) { free( handle->unicap_handle ); } CLOSE( handle->fd ); sem_destroy( &handle->sema ); free( handle ); return STATUS_SUCCESS; } static int v4l2_get_bpp( struct v4l2_fmtdesc *fmt ) { int bpp = 0; int i; for( i = 0; i < ( sizeof( fourcc_bpp_map ) / sizeof( struct fourcc_bpp ) ); i++ ) { if( fourcc_bpp_map[i].fourcc == fmt->pixelformat ) { bpp = fourcc_bpp_map[i].bpp; break; } } return bpp; } static unicap_rect_t *try_enum_framesizes( v4l2_handle_t handle, __u32 fourcc, int *pcount ) { #ifndef VIDIOC_ENUM_FRAMESIZES TRACE( "ENUM_FRAMESIZES not supported\n" ); return NULL; #else int nfound = 0; struct v4l2_frmsizeenum frms; unicap_rect_t *sizes; frms.pixel_format = fourcc; for( frms.index = 0; IOCTL( handle->fd, VIDIOC_ENUM_FRAMESIZES, &frms ) == 0; frms.index++ ) { if( frms.type == V4L2_FRMSIZE_TYPE_DISCRETE ) { nfound++; } else { TRACE( "VIDIOC_ENUM_FRAME_SIZES returned unsupported type\n" ); return NULL; } } /* If the IOCTL fails the first time this means the cam doesn't support VIDIOC_ENUM_FRAME_SIZES ! */ if (!nfound) return NULL; sizes = malloc( sizeof( unicap_rect_t ) * nfound ); for( frms.index = 0; ( frms.index < nfound ) && ( IOCTL( handle->fd, VIDIOC_ENUM_FRAMESIZES, &frms ) == 0 ); frms.index++ ) { if( handle->compat && handle->compat->override_framesize_func ) { handle->compat->override_framesize_func( handle, &frms ); } if( frms.type == V4L2_FRMSIZE_TYPE_DISCRETE ) { sizes[frms.index].x = 0; sizes[frms.index].y = 0; sizes[frms.index].width = frms.discrete.width; sizes[frms.index].height = frms.discrete.height; } else { TRACE( "VIDIOC_ENUM_FRAME_SIZES returned unsupported type\n" ); return NULL; } } TRACE( "found %d framesizes for fourcc: %08x\n", nfound, fourcc ); *pcount = nfound; return sizes; #endif } /* Check if format is supported (use VIDIOC_TRY_FMT if available). Return 0 if fmt can be selected. */ static int try_format( int fd, struct v4l2_format *fmt ) { int res = IOCTL( fd, VIDIOC_TRY_FMT, fmt ); if( res != 0 ) { TRACE( "VIDIOC_TRY_FMT ioctl failed: %s\n", strerror( errno ) ); res = IOCTL( fd, VIDIOC_S_FMT, fmt ); if( res != 0 ) { TRACE( "VIDIOC_S_FMT ioctl failed: %s\n", strerror( errno ) ); } } return res; } static unicap_rect_t *build_format_size_table( v4l2_handle_t handle, __u32 fourcc, int *pcount ) { int nfound = 0; int i; unicap_rect_t sfound[sizeof(try_sizes)/sizeof(unicap_rect_t)]; struct v4l2_format v4l2_fmt; unicap_rect_t *sizes = NULL; int n; handle->sizes_allocated = 1; memset( sfound, 0x0, sizeof( sfound ) ); sizes = try_enum_framesizes( handle, fourcc, pcount ); if( sizes ) { return sizes; } // First check whether the sizes for the device are already known n = sizeof( format_size_map ) / sizeof( struct size_map_s ); for( i = 0; i < n; i++ ) { if( !strncmp( format_size_map[i].card_name, handle->card_name, sizeof( format_size_map[i].card_name ) ) ) { handle->sizes_allocated = 0; *pcount = format_size_map[i].size_count; return format_size_map[i].sizes; } } for( i = 0; i < sizeof(try_sizes)/sizeof(unicap_rect_t); i++ ) { v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_fmt.fmt.pix.width = try_sizes[i].width; v4l2_fmt.fmt.pix.height = try_sizes[i].height; v4l2_fmt.fmt.pix.pixelformat = fourcc; v4l2_fmt.fmt.pix.field = V4L2_FIELD_ANY; if( try_format( handle->fd, &v4l2_fmt ) == 0 ) { int j; int found_fmt = 0; for( j = 0; j < nfound; j++ ) { if( ( sfound[j].width == v4l2_fmt.fmt.pix.width ) && ( sfound[j].height == v4l2_fmt.fmt.pix.height ) ) { found_fmt = 1; break; } } if( !found_fmt ) { sfound[nfound].width = v4l2_fmt.fmt.pix.width; sfound[nfound].height = v4l2_fmt.fmt.pix.height; TRACE( "Found new size: %dx%d\n", sfound[nfound].width, sfound[nfound].height ); nfound++; } } } if( nfound ) { sizes = malloc( sizeof( unicap_rect_t ) * nfound ); memcpy( sizes, sfound, nfound * sizeof( unicap_rect_t ) ); } *pcount = nfound; return sizes; } static unicap_status_t v4l2_reenumerate_formats( void *cpi_data, int *_pcount ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; int count; struct v4l2_fmtdesc v4l2_fmt; struct v4l2_cropcap v4l2_crop; struct v4l2_cropcap v4l2_crop_orig; if( handle->unicap_formats && handle->sizes_allocated ) { int i; for( i = 0; i < handle->format_count; i++ ) { if( handle->unicap_formats[i].sizes ) { free( handle->unicap_formats[i].sizes ); } } free( handle->unicap_formats ); handle->unicap_formats = 0; } memset( handle->format_mask, 0x0, sizeof( handle->format_mask ) ); count = 0; handle->unicap_formats = (unicap_format_t *) calloc( MAX_V4L2_FORMATS, sizeof( unicap_format_t ) ); v4l2_crop_orig.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( IOCTL( handle->fd, VIDIOC_CROPCAP, &v4l2_crop_orig ) < 0 ) { v4l2_crop_orig.defrect.width = v4l2_crop_orig.bounds.width = 768; v4l2_crop_orig.defrect.height = v4l2_crop_orig.bounds.height = 576; } v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; for( v4l2_fmt.index = 0; !IOCTL( handle->fd, VIDIOC_ENUM_FMT, &v4l2_fmt ); v4l2_fmt.index++ ) { int size_count; unicap_rect_t *sizes; char *identifier; unsigned int fourcc; int bpp; char tmp_identifier[128]; memcpy( &v4l2_crop, &v4l2_crop_orig, sizeof( v4l2_crop ) ); sprintf( tmp_identifier, "%s ( %c%c%c%c )", v4l2_fmt.description, ( v4l2_fmt.pixelformat & 0xff ), ( v4l2_fmt.pixelformat >> 8 & 0xff ), ( v4l2_fmt.pixelformat >> 16 & 0xff ), ( v4l2_fmt.pixelformat >> 24 & 0xff ) ); identifier = tmp_identifier; bpp = v4l2_get_bpp( &v4l2_fmt ); fourcc = v4l2_fmt.pixelformat; if( handle->compat && ( handle->compat->fmt_get_func( &v4l2_fmt, &v4l2_crop, &identifier, &fourcc, &bpp ) == STATUS_SKIP_CTRL ) ) { handle->format_mask[v4l2_fmt.index] = 1; handle->unicap_formats[v4l2_fmt.index].size_count = 0; continue; } count++; strcpy( handle->unicap_formats[v4l2_fmt.index].identifier, identifier ); handle->unicap_formats[v4l2_fmt.index].bpp = bpp; handle->unicap_formats[v4l2_fmt.index].fourcc = fourcc; TRACE( "enum format: index %d desc %s\n", v4l2_fmt.index, v4l2_fmt. description ); handle->unicap_formats[v4l2_fmt.index].size.width = v4l2_crop.defrect.width; handle->unicap_formats[v4l2_fmt.index].size.height = v4l2_crop.defrect.height; handle->unicap_formats[v4l2_fmt.index].buffer_type = UNICAP_BUFFER_TYPE_USER; sizes = build_format_size_table( handle, v4l2_fmt.pixelformat, &size_count ); if( sizes == NULL ){ handle->unicap_formats[v4l2_fmt.index].min_size.width = handle->unicap_formats[v4l2_fmt.index].min_size.height = 1; handle->unicap_formats[v4l2_fmt.index].max_size.width = v4l2_crop.bounds.width; handle->unicap_formats[v4l2_fmt.index].max_size.height = v4l2_crop.bounds.height; if( v4l2_crop.defrect.width && v4l2_crop.defrect.height ){ handle->unicap_formats[v4l2_fmt.index].buffer_size = v4l2_crop.defrect.width * v4l2_crop.defrect.height * handle->unicap_formats[v4l2_fmt.index].bpp / 8; }else{ handle->unicap_formats[v4l2_fmt.index].buffer_size = v4l2_crop.bounds.width * v4l2_crop.bounds.height * handle->unicap_formats[v4l2_fmt.index].bpp / 8; } handle->unicap_formats[v4l2_fmt.index].h_stepping = 16; handle->unicap_formats[v4l2_fmt.index].v_stepping = 16; handle->unicap_formats[v4l2_fmt.index].sizes = 0; handle->unicap_formats[v4l2_fmt.index].size_count = 0; }else{ // TODO : fix: currently assuming smallest format is first; // largest is last int i; int min_width = 0x7fffffff; int max_width = 0; int min_height = 0x7fffffff; int max_height = 0; for( i = 0; i < size_count; i++ ){ if( sizes[i].width < min_width ){ min_width = sizes[i].width; } if( sizes[i].width > max_width ){ max_width = sizes[i].width; } if( sizes[i].height < min_height ){ min_height = sizes[i].height; } if( sizes[i].height > max_height ){ max_height = sizes[i].height; } } handle->unicap_formats[v4l2_fmt.index].min_size.width = min_width; handle->unicap_formats[v4l2_fmt.index].min_size.height = min_height; handle->unicap_formats[v4l2_fmt.index].max_size.width = max_width; handle->unicap_formats[v4l2_fmt.index].max_size.height = max_height; handle->unicap_formats[v4l2_fmt.index].sizes = sizes; handle->unicap_formats[v4l2_fmt.index].size_count = size_count; handle->unicap_formats[v4l2_fmt.index].buffer_size = ( sizes[size_count-1].width * sizes[size_count-1].height * handle->unicap_formats[v4l2_fmt.index].bpp / 8 ); } v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } handle->format_count = v4l2_fmt.index; handle->supported_formats = count; if( _pcount ){ *_pcount = count; } return STATUS_SUCCESS; } static unicap_status_t v4l2_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; int tmp_index, i, v4l2index = 0; unicap_status_t status = STATUS_NO_MATCH; /* TRACE( "enumerate formats: %d (%d)\n", index, handle->format_count ); */ if( index >= handle->format_count ) { return STATUS_NO_MATCH; } for( i = 0, tmp_index = -1; ( i < handle->format_count ) && ( tmp_index != index ); i++ ) { if( handle->format_mask[i] == 0 ) { tmp_index++; v4l2index = i; } } if( tmp_index == index ) { unicap_copy_format( format, &handle->unicap_formats[v4l2index] ); status = STATUS_SUCCESS; } return status; } static unicap_status_t v4l2_set_format( void *cpi_data, unicap_format_t *_format ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; struct v4l2_format v4l2_fmt; int i; int index = -1; __u32 fourcc; unicap_format_t format; int old_running = handle->capture_running; if( handle->capture_running ){ v4l2_capture_stop( handle ); } unicap_copy_format( &format, _format ); TRACE( "v4l2_set_format\n" ); for( i = 0; i < handle->format_count; i++ ) { if( !strcmp( format.identifier, handle->unicap_formats[ i ].identifier ) ) { index = i; break; } } if( index == -1 ) { TRACE( "v4l2_set_format failed: NO_MATCH\n" ); return STATUS_NO_MATCH; } unicap_copy_format( &handle->current_format, &format ); handle->current_format.buffer_size = format.size.width * format.size.height * format.bpp / 8; if( handle->compat && handle->compat->tov4l2format_func ) { handle->compat->tov4l2format_func( handle, &format ); } else { fourcc = handle->unicap_formats[ index ].fourcc; } v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_fmt.fmt.pix.width = format.size.width; v4l2_fmt.fmt.pix.height = format.size.height; v4l2_fmt.fmt.pix.pixelformat = format.fourcc;/* handle->unicap_formats[ index ].fourcc; */ if ((format.flags & UNICAP_FLAGS_FIELD_ALTERNATE) == UNICAP_FLAGS_FIELD_ALTERNATE){ v4l2_fmt.fmt.pix.field = V4L2_FIELD_ALTERNATE; } else { v4l2_fmt.fmt.pix.field = V4L2_FIELD_ANY; } if( IOCTL( handle->fd, VIDIOC_S_FMT, &v4l2_fmt ) < 0 ) { TRACE( "VIDIOC_S_FMT ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( old_running ){ v4l2_capture_start( handle ); } return STATUS_SUCCESS; } static unicap_status_t v4l2_get_format( void *cpi_data, unicap_format_t *format ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; unicap_copy_format( format, &handle->current_format ); return STATUS_SUCCESS; } static unicap_status_t v4l2_enum_frameintervals( v4l2_handle_t handle, unicap_property_t *property ) { #ifdef VIDIOC_ENUM_FRAMEINTERVALS unicap_format_t format; struct v4l2_frmivalenum frmival; int is_range = 0; TRACE( "v4l2_enum_frameintervals\n" ); v4l2_get_format( handle, &format ); if( !format.fourcc ) { return STATUS_FAILURE; } if( handle->compat && handle->compat->tov4l2format_func ) { handle->compat->tov4l2format_func( handle, &format ); } frmival.pixel_format = format.fourcc; frmival.width = format.size.width; frmival.height = format.size.height; handle->frame_rate_count = 0; for( frmival.index = 0; ( frmival.index < V4L2_MAX_FRAME_RATES ) && ( IOCTL( handle->fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival ) >= 0 ); frmival.index++ ) { int i; int is_dublette = 0; if( frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE ) { handle->frame_rates[ handle->frame_rate_count ] = 1/((double)frmival.discrete.numerator / (double)frmival.discrete.denominator); TRACE( "num: %d denom: %d\n", frmival.discrete.numerator, frmival.discrete.denominator ); } else { is_range = 1; } // Some devices enumerate the same frame interval over and over - filter out // those for( i = 0; i < handle->frame_rate_count; i++ ) { if( handle->frame_rates[ handle->frame_rate_count ] == handle->frame_rates[ i ] ) { is_dublette = 1; break; } } if( !is_dublette ) { handle->frame_rate_count++; } } if( frmival.index == 0 ) { return STATUS_FAILURE; } property->relations = 0; property->relations_count = 0; property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; property->property_data = 0; property->property_data_size = 0; strcpy( property->identifier, V4L2_VIDEO_FRAMERATE_PPTY_NAME ); strcpy( property->category, "video" ); strcpy( property->unit, "" ); if (is_range){ handle->frame_rates[ handle->frame_rate_count ] = 1/((double)frmival.stepwise.max.numerator / (double)frmival.stepwise.max.denominator); property->range.min = 1/((double)frmival.stepwise.max.numerator / (double)frmival.stepwise.max.denominator); property->range.max = 1/((double)frmival.stepwise.min.numerator / (double)frmival.stepwise.min.denominator); /* property->stepping = 1/((double)frmival.stepwise.step.numerator / (double)frmival.stepwise.step.denominator); */ property->stepping = (property->range.max - property->range.min) / 100.0; } else { property->value_list.values = handle->frame_rates; property->value_list.value_count = handle->frame_rate_count; property->value = property->value_list.values[0]; property->stepping = 0; property->type = UNICAP_PROPERTY_TYPE_VALUE_LIST; } return STATUS_SUCCESS; #else // ndef VIDIOC_ENUM_FRAMEINTERVALS return STATUS_FAILURE; #endif } static unicap_status_t v4l2_set_frame_interval( v4l2_handle_t handle, unicap_property_t *property ) { #ifdef VIDIOC_S_PARM struct v4l2_streamparm parm; int running = handle->capture_running; v4l2_capture_stop( handle ); parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.timeperframe.numerator = 100; parm.parm.capture.timeperframe.denominator = property->value * 100; if( IOCTL( handle->fd, VIDIOC_S_PARM, &parm ) < 0 ) { TRACE( "Failed to set frame interval: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( running ) { v4l2_capture_start( handle ); } return STATUS_SUCCESS; #else return STATUS_FAILURE; #endif } static unicap_status_t v4l2_get_frame_interval( v4l2_handle_t handle, unicap_property_t *property ) { #ifdef VIDIOC_G_PARM struct v4l2_streamparm parm; parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( IOCTL( handle->fd, VIDIOC_G_PARM, &parm ) < 0 ) { TRACE( "Failed to get frame interval\n" ); return STATUS_FAILURE; } property->value = 1/( (double)parm.parm.capture.timeperframe.numerator / (double) parm.parm.capture.timeperframe.denominator ); return STATUS_SUCCESS; #else return STATUS_FAILURE; #endif } static unicap_status_t v4l2_enum_inputs( v4l2_handle_t handle, unicap_property_t *property ) { struct v4l2_input input; for( input.index = 0; (input.index < V4L2_MAX_VIDEO_INPUTS ) && ( IOCTL( handle->fd, VIDIOC_ENUMINPUT, &input ) == 0 ); input.index++ ) { strncpy( handle->video_inputs[input.index], (char*)input.name, 32 ); } // Only present inputs if there are more than one if( input.index <= 1 ) { return STATUS_FAILURE; } property->menu.menu_items = handle->video_inputs; property->menu.menu_item_count = input.index; strcpy( property->identifier, V4L2_VIDEO_IN_PPTY_NAME ); strcpy( property->category, N_("source") ); strcpy( property->unit, "" ); property->relations = 0; property->relations_count = 0; strcpy( property->menu_item, property->menu.menu_items[0] ); property->stepping = 0; property->type = UNICAP_PROPERTY_TYPE_MENU; property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; property->property_data = 0; property->property_data_size = 0; handle->video_in_count = input.index; return STATUS_SUCCESS; } static unicap_status_t v4l2_enum_norms( v4l2_handle_t handle, unicap_property_t *property ) { struct v4l2_input input; struct v4l2_standard standard; if( IOCTL( handle->fd, VIDIOC_G_INPUT, &input.index ) < 0 ) { TRACE( "Failed to get input\n" ); return STATUS_FAILURE; } input.index = 0; if( IOCTL( handle->fd, VIDIOC_ENUMINPUT, &input ) < 0 ) { TRACE( "Failed to enumerate input\n" ); return STATUS_FAILURE; } standard.index = 0; while( IOCTL( handle->fd, VIDIOC_ENUMSTD, &standard ) == 0 ) { if( standard.id && input.std ) { TRACE ("Found norm: %s\n", standard.name); strcpy( handle->video_norms[standard.index], (char*)standard.name ); } standard.index++; } /* From v4l2-draft: EINVAL indicates the end of the enumeration, which cannot be empty unless this device falls under the USB exception. */ if( errno != EINVAL || standard.index == 0 ) { TRACE( "Failed to enumerate norms\n" ); return STATUS_FAILURE; } property->menu.menu_items = (char**)handle->video_norms; property->menu.menu_item_count = standard.index; strcpy( property->identifier, V4L2_VIDEO_NORM_PPTY_NAME ); strcpy( property->category, "source" ); strcpy( property->unit, "" ); property->relations = 0; property->relations_count = 0; strcpy( property->menu_item, property->menu.menu_items[0] ); property->stepping = 0; property->type = UNICAP_PROPERTY_TYPE_MENU; property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; property->property_data = 0; property->property_data_size = 0; TRACE( "-enum_norms\n" ); return STATUS_SUCCESS; } static char *get_category( char *identifier ) { char *cat = "video"; int i; for( i = 0; i < ( sizeof( category_list ) / sizeof( struct prop_category ) ); i++ ) { if( !strcasecmp( category_list[i].property_id, identifier ) ) { cat = category_list[i].category; break; } } return cat; } static unicap_status_t default_override_property( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( !ctrl ) { return STATUS_NO_MATCH; } switch( ctrl->id ) { case V4L2_CID_EXPOSURE_ABSOLUTE: { if( property ) { strcpy( property->identifier, N_("shutter") ); strcpy( property->category, N_("exposure") ); strcpy( property->unit, N_("s") ); property->flags_mask = UNICAP_FLAGS_MANUAL; property->flags = UNICAP_FLAGS_MANUAL; property->type = UNICAP_PROPERTY_TYPE_RANGE; property->range.min = (double)ctrl->minimum / 10000.0; property->range.max = (double)ctrl->maximum / 10000.0; property->value = (double)ctrl->default_value / 10000.0; property->relations = NULL; property->relations_count = 0; property->property_data_size = 0; property->property_data = NULL; } status = STATUS_SUCCESS; } break; default: break; } if( SUCCESS( status ) ) { TRACE( "Using default override for property '%s'\n", property->identifier ); } return status; } static unicap_status_t add_properties( v4l2_handle_t handle, int index_start, int index_end, int *ppty_index ) { int index; struct v4l2_queryctrl v4l2ctrl; int tmp_ppty_index = *ppty_index; memset( &v4l2ctrl, 0x0, sizeof( v4l2ctrl ) ); for( index = index_start; index < index_end; index++ ) { v4l2ctrl.id = index; if( IOCTL( handle->fd, VIDIOC_QUERYCTRL, &v4l2ctrl ) ) { if( errno == EINVAL ) { continue; } TRACE( "ioctl failed\n" ); perror( "error" ); return STATUS_FAILURE; } if( !(v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { override_property_func_t override_func = default_override_property; if( handle->compat && handle->compat->override_property_func ) override_func = handle->compat->override_property_func; unicap_status_t status = override_func( handle, &v4l2ctrl, &handle->unicap_properties[ tmp_ppty_index ] ); if( status == STATUS_SUCCESS ) { tmp_ppty_index++; continue; } if( status == STATUS_SKIP_CTRL ) { continue; } TRACE( "add property: %s\n", v4l2ctrl.name ); strcpy( handle->unicap_properties[ tmp_ppty_index ].identifier, (char*)v4l2ctrl.name ); handle->unicap_properties[ tmp_ppty_index ].value = v4l2ctrl.default_value; if( v4l2ctrl.type != V4L2_CTRL_TYPE_BOOLEAN ) { handle->unicap_properties[ tmp_ppty_index ].range.min = v4l2ctrl.minimum; handle->unicap_properties[ tmp_ppty_index ].range.max = v4l2ctrl.maximum; handle->unicap_properties[ tmp_ppty_index ].stepping = v4l2ctrl.step; } else { handle->unicap_properties[ tmp_ppty_index ].range.min = 0; handle->unicap_properties[ tmp_ppty_index ].range.max = 1; handle->unicap_properties[ tmp_ppty_index ].stepping = 1; } handle->unicap_properties[ tmp_ppty_index ].type = UNICAP_PROPERTY_TYPE_RANGE; strcpy( handle->unicap_properties[ tmp_ppty_index ].category, get_category( handle->unicap_properties[ tmp_ppty_index ].identifier ) ); strcpy( handle->unicap_properties[ tmp_ppty_index ].unit, "" ); handle->unicap_properties[ tmp_ppty_index ].relations = 0; handle->unicap_properties[ tmp_ppty_index ].relations_count = 0; handle->unicap_properties[ tmp_ppty_index ].flags = UNICAP_FLAGS_MANUAL; handle->unicap_properties[ tmp_ppty_index ].flags_mask = UNICAP_FLAGS_MANUAL; handle->unicap_properties[ tmp_ppty_index ].property_data = 0; handle->unicap_properties[ tmp_ppty_index ].property_data_size = 0; handle->control_ids[ tmp_ppty_index ] = index; tmp_ppty_index++; } } *ppty_index = tmp_ppty_index; return STATUS_SUCCESS; } static int count_properties( v4l2_handle_t handle, int index_start, int index_end ) { struct v4l2_queryctrl v4l2ctrl; int index; int count = 0; for( index = index_start; index < index_end; index++ ) { v4l2ctrl.id = index; if( IOCTL( handle->fd, VIDIOC_QUERYCTRL, &v4l2ctrl ) ) { if( errno == EINVAL ) { continue; } TRACE( "ioctl failed at index: %d\n", index ); perror( "error" ); continue; } if( (handle->compat) && (!v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED) && ( handle->compat->override_property_func ) ) { unicap_status_t status = handle->compat->override_property_func( handle, &v4l2ctrl, NULL ); if( status == STATUS_SKIP_CTRL ) { continue; } } if( !v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED ) { count++; } } return count; } static unicap_status_t add_properties_ext( v4l2_handle_t handle, int *ppty_index ) { #ifdef V4L2_CTRL_FLAG_NEXT_CTRL struct v4l2_queryctrl v4l2ctrl; int tmp_ppty_index = *ppty_index; int ret; v4l2ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; while( ret = IOCTL( handle->fd, VIDIOC_QUERYCTRL, &v4l2ctrl ) == 0 ) { TRACE( "++%s++\n", v4l2ctrl.name ); override_property_func_t override_func = default_override_property; if( handle->compat && handle->compat->override_property_func ) override_func = handle->compat->override_property_func; if( !(v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED) ) { unicap_status_t status = override_func( handle, &v4l2ctrl, &handle->unicap_properties[ tmp_ppty_index ] ); if( status == STATUS_SUCCESS ) { v4l2ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; TRACE( "Added from compat: %s\n", v4l2ctrl.name ); tmp_ppty_index++; continue; } if( status == STATUS_SKIP_CTRL ) { v4l2ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; TRACE( "Skip: %s\n", v4l2ctrl.name ); continue; } } v4l2ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; if( !v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED ) { TRACE( "add property: %s\n", v4l2ctrl.name ); strcpy( handle->unicap_properties[ tmp_ppty_index ].identifier, (char*)v4l2ctrl.name ); handle->unicap_properties[ tmp_ppty_index ].value = v4l2ctrl.default_value; if( v4l2ctrl.type != V4L2_CTRL_TYPE_BOOLEAN ) { handle->unicap_properties[ tmp_ppty_index ].range.min = v4l2ctrl.minimum; handle->unicap_properties[ tmp_ppty_index ].range.max = v4l2ctrl.maximum; handle->unicap_properties[ tmp_ppty_index ].stepping = v4l2ctrl.step; } else { handle->unicap_properties[ tmp_ppty_index ].range.min = 0; handle->unicap_properties[ tmp_ppty_index ].range.max = 1; handle->unicap_properties[ tmp_ppty_index ].stepping = 1; } handle->unicap_properties[ tmp_ppty_index ].type = UNICAP_PROPERTY_TYPE_RANGE; strcpy( handle->unicap_properties[ tmp_ppty_index ].category, get_category( handle->unicap_properties[ tmp_ppty_index ].identifier ) ); strcpy( handle->unicap_properties[ tmp_ppty_index ].unit, "" ); handle->unicap_properties[ tmp_ppty_index ].relations = 0; handle->unicap_properties[ tmp_ppty_index ].relations_count = 0; handle->unicap_properties[ tmp_ppty_index ].flags = UNICAP_FLAGS_MANUAL; handle->unicap_properties[ tmp_ppty_index ].flags_mask = UNICAP_FLAGS_MANUAL; handle->unicap_properties[ tmp_ppty_index ].property_data = 0; handle->unicap_properties[ tmp_ppty_index ].property_data_size = 0; if( v4l2ctrl.flags & V4L2_CTRL_FLAG_READ_ONLY ) { handle->unicap_properties[ tmp_ppty_index ].flags |= UNICAP_FLAGS_READ_ONLY; } handle->control_ids[ tmp_ppty_index ] = v4l2ctrl.id & V4L2_CTRL_ID_MASK; tmp_ppty_index++; } else{ TRACE( "disabled property: %s\n", v4l2ctrl.name ); } } *ppty_index = tmp_ppty_index; return STATUS_SUCCESS; #else return STATUS_NOT_IMPLEMENTED; #endif } static int count_properties_ext( v4l2_handle_t handle ) { #ifdef V4L2_CTRL_FLAG_NEXT_CTRL struct v4l2_queryctrl v4l2ctrl; int count = 0; v4l2ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; while( IOCTL( handle->fd, VIDIOC_QUERYCTRL, &v4l2ctrl ) == 0 ) { if( (handle->compat) && (!v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED) && ( handle->compat->override_property_func ) ) { unicap_status_t status = handle->compat->override_property_func( handle, &v4l2ctrl, NULL ); if( status == STATUS_SKIP_CTRL ) { v4l2ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; continue; } } if( !v4l2ctrl.flags & V4L2_CTRL_FLAG_DISABLED ) { count++; } v4l2ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; } return count; #else return 0; #endif } static unicap_status_t v4l2_reenumerate_properties( void *cpi_data, int *_pcount ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; int count = 0; int compat_count = 0; int index = 0; int ppty_index = 0; int use_extended_ctrl = 0; TRACE( "v4l2_reenumerate_properties\n" ); if( handle->unicap_properties ) { free( handle->unicap_properties ); handle->unicap_properties = 0; } if( handle->control_ids ) { free( handle->control_ids ); handle->control_ids = 0; } count = count_properties_ext( handle ); if( count > 1 ) { TRACE( "Use extended control interface\n" ); use_extended_ctrl = 1; } else { count = count_properties( handle, V4L2_CID_BASE, V4L2_CID_BASE + 0x1000 ); count += count_properties( handle, V4L2_CID_PRIVATE_BASE, V4L2_CID_PRIVATE_BASE + 0x1000 ); count += count_properties( handle, V4L2_CID_CAMERA_CLASS_BASE, V4L2_CID_CAMERA_CLASS_BASE + 0x1000 ); /* #ifdef V4L2_CID_USER_BASE */ /* count += count_properties( handle, V4L2_CID_USER_BASE, V4L2_CID_USER_BASE + 0x1000 ); */ /* #endif */ } count++;// video input source property count++;// video norm property count++;// frame rate property if( handle->compat ) { compat_count = handle->compat->count_ext_property_func( handle ); count += compat_count; } handle->unicap_properties = (unicap_property_t *) malloc( count * sizeof( unicap_property_t ) ); handle->control_ids = (__u32*) malloc( count * sizeof( __u32 ) ); handle->property_count = count; if( use_extended_ctrl ) { if( !SUCCESS( add_properties_ext( handle, &ppty_index ) ) ) { TRACE( "add_properties_ext failed\n" ); return STATUS_FAILURE; } } else { if( !SUCCESS( add_properties( handle, V4L2_CID_BASE, V4L2_CID_BASE + 0x1000, &ppty_index ) ) || !SUCCESS( add_properties( handle, V4L2_CID_PRIVATE_BASE, V4L2_CID_PRIVATE_BASE + 0x1000, &ppty_index ) ) || !SUCCESS( add_properties( handle, V4L2_CID_CAMERA_CLASS_BASE, V4L2_CID_CAMERA_CLASS_BASE + 0x1000, &ppty_index ) ) ) { return STATUS_FAILURE; } } /* #ifdef V4L2_CID_USER_BASE */ /* if( !SUCCESS( add_properties( handle, V4L2_CID_USER_BASE, V4L2_CID_USER_BASE + 0x1000, &ppty_index ) ) ) */ /* { */ /* return STATUS_FAILURE; */ /* } */ /* #endif */ if( !SUCCESS( v4l2_enum_inputs( handle, &handle->unicap_properties[ ppty_index++ ] ) ) ) { handle->property_count--; ppty_index--; } if( !SUCCESS( v4l2_enum_norms( handle, &handle->unicap_properties[ ppty_index++ ] ) ) ) { handle->property_count--; ppty_index--; } if( !SUCCESS( v4l2_enum_frameintervals( handle, &handle->unicap_properties[ ppty_index ] ) ) ) { handle->property_count--; ppty_index--; } else { if( handle->compat && handle->compat->override_property_func ) { handle->compat->override_property_func( handle, NULL, &handle->unicap_properties[ ppty_index ] ); } } ppty_index++; if( handle->compat ) { for( index = 0; index < compat_count; index++ ) { if( !SUCCESS( handle->compat->enumerate_property_func( handle, index, &handle->unicap_properties[ ppty_index++ ] ) ) ) { handle->property_count--; ppty_index--; } } } if( _pcount ) { *_pcount = ppty_index; } return STATUS_SUCCESS; } static unicap_status_t v4l2_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; if( index >= handle->property_count ) { return STATUS_NO_MATCH; } unicap_copy_property( property, &handle->unicap_properties[index] ); return STATUS_SUCCESS; } static unicap_status_t v4l2_set_input( v4l2_handle_t handle, unicap_property_t *property ) { struct v4l2_input input; for( input.index = 0; input.index < handle->video_in_count; input.index++ ) { if( !strcmp( property->menu_item, handle->video_inputs[input.index] ) ) { if( IOCTL( handle->fd, VIDIOC_S_INPUT, &input ) == 0 ) { return STATUS_SUCCESS; } else { return STATUS_FAILURE; } } } return STATUS_NO_MATCH; } static unicap_status_t v4l2_set_norm( v4l2_handle_t handle, unicap_property_t *property ) { struct v4l2_input input; struct v4l2_standard standard; v4l2_std_id id=0; if( IOCTL( handle->fd, VIDIOC_G_INPUT, &input.index ) < 0 ) { TRACE( "Failed to get input\n" ); return STATUS_FAILURE; } input.index = 0; if( IOCTL( handle->fd, VIDIOC_ENUMINPUT, &input ) < 0 ) { TRACE( "Failed to enumerate input\n" ); return STATUS_FAILURE; } standard.index = 0; while( IOCTL( handle->fd, VIDIOC_ENUMSTD, &standard ) == 0 ) { if( standard.id & input.std ) { TRACE ("Found norm: %s [%016llx], looking for: %s\n", standard.name, standard.id, property->menu_item); if( !strcmp( property->menu_item, (char*)standard.name ) ) { id = standard.id; break; } } standard.index++; } TRACE( "Set norm: %016llx\n", id ); if( IOCTL( handle->fd, VIDIOC_S_STD, &id ) < 0 ) { TRACE( "Failed to set norm: %016llx %016llx\n", id, input.std ); return STATUS_FAILURE; } return STATUS_SUCCESS; } static unicap_status_t v4l2_set_property( void *cpi_data, unicap_property_t *property ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; unicap_status_t status; int index; TRACE( "v4l2_set_property\n" ); if( handle->compat ) { status = handle->compat->set_property_func( handle, property ); if( status != STATUS_NO_MATCH ) { return status; } } if (!strcmp (property->identifier, "shutter")) { struct v4l2_control ctrl; ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE; ctrl.value = property->value * 10000; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } } if( !strcmp( property->identifier, V4L2_VIDEO_IN_PPTY_NAME ) ) { return v4l2_set_input( handle, property ); } if( !strcmp( property->identifier, V4L2_VIDEO_NORM_PPTY_NAME ) ) { return v4l2_set_norm( handle, property ); } if( !strcmp( property->identifier, V4L2_VIDEO_FRAMERATE_PPTY_NAME ) ) { return v4l2_set_frame_interval( handle, property ); } for( index = 0; index < handle->property_count; index++ ) { if( !strcmp( property->identifier, handle->unicap_properties[index].identifier ) ) { struct v4l2_control v4l2ctrl; v4l2ctrl.id = handle->control_ids[ index ]; v4l2ctrl.value = property->value; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &v4l2ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } return STATUS_SUCCESS; } } return STATUS_NO_MATCH; } static unicap_status_t v4l2_get_input( v4l2_handle_t handle, unicap_property_t *property ) { struct v4l2_input input; if( !IOCTL( handle->fd, VIDIOC_G_INPUT, &input ) ) { strcpy( property->menu_item, handle->video_inputs[input.index] ); return STATUS_SUCCESS; } return STATUS_FAILURE; } static unicap_status_t v4l2_get_norm( v4l2_handle_t handle, unicap_property_t *property ) { struct v4l2_standard standard; v4l2_std_id id=0; unicap_status_t status = STATUS_FAILURE; if( IOCTL( handle->fd, VIDIOC_G_STD, &id ) < 0 ) { TRACE( "Failed to get norm\n" ); return STATUS_FAILURE; } standard.index = 0; while( IOCTL( handle->fd, VIDIOC_ENUMSTD, &standard ) == 0 ) { if( standard.id & id ) { TRACE ("Found norm: %s [%016llx]", standard.name, standard.id ); strcpy( property->menu_item, (char*)standard.name ); status = STATUS_SUCCESS; break; } standard.index++; } return status; } static unicap_status_t v4l2_get_property( void *cpi_data, unicap_property_t *property ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; unicap_status_t status; int index; /* TRACE( "v4l2_get_property\n" ); */ for( index = 0; index < handle->property_count; index++ ) { if( !strcmp( property->identifier, handle->unicap_properties[index].identifier ) ) { struct v4l2_control v4l2ctrl; unicap_copy_property( property, &handle->unicap_properties[ index ] ); if( handle->compat ) { status = handle->compat->get_property_func( handle, property ); if( status != STATUS_NO_MATCH ) { return status; } } if (!strcmp (property->identifier, "shutter")) { struct v4l2_control ctrl; ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed!\n" ); return STATUS_FAILURE; } property->value = (double)ctrl.value / 10000.0; return STATUS_SUCCESS; } if( !strcmp( property->identifier, V4L2_VIDEO_IN_PPTY_NAME ) ) { return v4l2_get_input( handle, property ); } if( !strcmp( property->identifier, V4L2_VIDEO_NORM_PPTY_NAME ) ) { return v4l2_get_norm( handle, property ); } if( !strcmp( property->identifier, V4L2_VIDEO_FRAMERATE_PPTY_NAME ) ) { return v4l2_get_frame_interval( handle, property ); } if( property->flags & UNICAP_FLAGS_WRITE_ONLY ) { property->value = 0.0; return STATUS_SUCCESS; } v4l2ctrl.id = handle->control_ids[ index ]; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &v4l2ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed\n" ); return STATUS_FAILURE; } property->value = v4l2ctrl.value; return STATUS_SUCCESS; } } return STATUS_NO_MATCH; } static unicap_status_t v4l2_capture_start( void *cpi_data ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; struct v4l2_requestbuffers v4l2_reqbuf; unicap_status_t status = STATUS_SUCCESS; TRACE( "v4l2_start_capture\n" ); if( handle->capture_running ) { return STATUS_CAPTURE_ALREADY_STARTED; } handle->buffer_mgr = buffer_mgr_create( handle->fd, &handle->current_format ); if (!handle->buffer_mgr) return STATUS_FAILURE; handle->capture_running = 1; status = buffer_mgr_queue_all( handle->buffer_mgr ); handle->quit_capture_thread = 0; pthread_create( &handle->capture_thread, NULL, (void*(*)(void*))v4l2_capture_thread, handle ); int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( IOCTL( handle->fd, VIDIOC_STREAMON, &type ) < 0 ){ TRACE( "VIDIOC_STREAMON ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } return status; } static unicap_status_t v4l2_capture_stop( void *cpi_data ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int i; TRACE( "v4l2_capture_stop\n" ); if( handle->capture_running ) { handle->capture_running = 0; handle->quit_capture_thread = 1; pthread_join( handle->capture_thread, NULL ); if( IOCTL( handle->fd, VIDIOC_STREAMOFF, &type ) < 0 ) { TRACE( "VIDIOC_STREAMOFF ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } buffer_mgr_dequeue_all (handle->buffer_mgr); buffer_mgr_destroy (handle->buffer_mgr); while( ucutil_get_front_queue( handle->in_queue ) ) { TRACE( "!!possible memleak\n" ); } } return STATUS_SUCCESS; } static unicap_status_t queue_buffer( v4l2_handle_t handle, unicap_data_buffer_t *buffer ) { struct v4l2_buffer v4l2_buffer; memset( &v4l2_buffer, 0x0, sizeof( v4l2_buffer ) ); v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.length = buffer->buffer_size; switch( handle->io_method ) { case CPI_V4L2_IO_METHOD_MMAP: { int ret = 0; v4l2_buffer.index = 0; v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.memory = V4L2_MEMORY_MMAP; if( sem_wait( &handle->sema ) ) { TRACE( "SEM_WAIT FAILED!\n" ); return STATUS_FAILURE; } if( ( ( handle->qindex + 1 ) % handle->buffer_count ) == handle->dqindex ) { TRACE( "NO BUFFERS\n" ); sem_post( &handle->sema ); return STATUS_NO_BUFFERS; } v4l2_buffer.index = handle->qindex; TRACE( "Q: index = %d type = %u, memory = %u\n", handle->qindex, v4l2_buffer.type, v4l2_buffer.memory ); handle->qindex = ( handle->qindex + 1 ) % handle->buffer_count; v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( ( ret = IOCTL( handle->fd, VIDIOC_QBUF, &v4l2_buffer ) ) < 0 ) { if( ( ret == -ENODEV ) && !handle->removed && handle->event_callback ) { handle->event_callback( handle->unicap_handle, UNICAP_EVENT_DEVICE_REMOVED ); handle->removed = 1; } TRACE( "VIDIOC_QBUF ioctl failed: %s\n", strerror( errno ) ); sem_post( &handle->sema ); return STATUS_FAILURE; } if( sem_post( &handle->sema ) ) { TRACE( "SEM_POST FAILED\n" ); return STATUS_FAILURE; } } break; case CPI_V4L2_IO_METHOD_USERPOINTER: { int ret; v4l2_buffer.m.userptr = ( unsigned long ) buffer->data; v4l2_buffer.memory = V4L2_MEMORY_USERPTR; v4l2_buffer.index = 0; if( ( ret = IOCTL( handle->fd, VIDIOC_QBUF, &v4l2_buffer ) ) < 0 ) { if( ( ret == -ENODEV ) && !handle->removed && handle->event_callback ) { handle->event_callback( handle->unicap_handle, UNICAP_EVENT_DEVICE_REMOVED ); handle->removed = 1; } TRACE( "VIDIOC_QBUF ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( ucutil_queue_get_size( handle->in_queue ) == 2 ) { } } break; default: return STATUS_FAILURE; } return STATUS_SUCCESS; } static unicap_status_t queue_system_buffers( v4l2_handle_t handle ) { struct v4l2_buffer v4l2_buffer; memset( &v4l2_buffer, 0x0, sizeof( v4l2_buffer ) ); v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.length = handle->current_format.buffer_size; switch( handle->io_method ) { case CPI_V4L2_IO_METHOD_MMAP: { int i; v4l2_buffer.index = 0; v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.memory = V4L2_MEMORY_MMAP; if( sem_wait( &handle->sema ) ) { TRACE( "SEM_WAIT FAILED!\n" ); return STATUS_FAILURE; } for( i = 0; i < handle->buffer_count; i++ ) { int ret; if( ( ( handle->qindex + 1 ) % handle->buffer_count ) == handle->dqindex ) { TRACE( "NO BUFFERS\n" ); sem_post( &handle->sema ); return STATUS_NO_BUFFERS; } v4l2_buffer.index = handle->qindex; TRACE( "Q: index = %d type = %u, memory = %u dqindex = %d\n", handle->qindex, v4l2_buffer.type, v4l2_buffer.memory, handle->dqindex ); handle->qindex = ( handle->qindex + 1 ) % handle->buffer_count; v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if( ( ret = IOCTL( handle->fd, VIDIOC_QBUF, &v4l2_buffer ) ) < 0 ) { if( ( ret == -ENODEV ) && !handle->removed && handle->event_callback ) { handle->event_callback( handle->unicap_handle, UNICAP_EVENT_DEVICE_REMOVED ); handle->removed = 1; } TRACE( "VIDIOC_QBUF ioctl failed: %s\n", strerror( errno ) ); sem_post( &handle->sema ); return STATUS_FAILURE; } if( sem_post( &handle->sema ) ) { TRACE( "SEM_POST FAILED\n" ); return STATUS_FAILURE; } } } break; default: return STATUS_FAILURE; } return STATUS_SUCCESS; } static unicap_status_t v4l2_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; struct _unicap_queue *queue = malloc( sizeof( struct _unicap_queue ) ); TRACE( "QUEUE\n" ); if( handle->capture_running ) { unicap_status_t status = queue_buffer( handle, buffer ); if( SUCCESS( status ) ){ queue->data = buffer; ucutil_insert_back_queue( handle->in_queue, queue ); }else{ TRACE( "queue buffer failed\n" ); free (queue); } if( ( status == STATUS_NO_BUFFERS ) && ( buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) ) { status = STATUS_SUCCESS; } } else { free (queue); } return STATUS_SUCCESS; } static unicap_status_t v4l2_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { /* v4l2_handle_t handle = (v4l2_handle_t) cpi_data; */ return STATUS_NOT_IMPLEMENTED; } static unicap_status_t v4l2_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; unicap_data_buffer_t *returned_buffer; unicap_queue_t *entry; TRACE( "WAIT\n" ); if( !handle->out_queue->next &&! handle->capture_running ) { TRACE( "Wait->capture stopped" ); return STATUS_IS_STOPPED; } while( !handle->out_queue->next ) { usleep( 1000 ); } if( handle->out_queue->next ) { entry = ucutil_get_front_queue( handle->out_queue ); returned_buffer = ( unicap_data_buffer_t * ) entry->data; free( entry ); *buffer = returned_buffer; } TRACE( "-WAIT\n" ); return STATUS_SUCCESS; } static unicap_status_t v4l2_poll_buffer( void *cpi_data, int *count ) { v4l2_handle_t handle = (v4l2_handle_t) cpi_data; /* TRACE( "POLL\n" ); */ *count = ucutil_queue_get_size( handle->out_queue ); return STATUS_SUCCESS; } static unicap_status_t v4l2_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ) { v4l2_handle_t handle = ( v4l2_handle_t )cpi_data; handle->event_callback = func; handle->unicap_handle = unicap_handle; return STATUS_SUCCESS; } /* Check if fd is readable, timing out after a short time (to allow the capture thread to check if it should stop). */ static int fd_readable( int fd ) { struct pollfd pfd = { .fd = fd, .events = POLLIN, .revents = 0 }; int timeout_ms = 100; return poll( &pfd, 1, timeout_ms ); } static void v4l2_capture_thread( v4l2_handle_t handle ) { unicap_data_buffer_t new_frame_buffer; /* struct sched_param param; */ /* param.sched_priority = 10; */ /* if( sched_setscheduler( 0, SCHED_FIFO, ¶m ) != 0 ) */ /* { */ /* } */ handle->dqindex = -1; while( !handle->quit_capture_thread ) { unicap_queue_t *entry; struct timeval ctime; int old_index; int drop = 0; int ret = 0; unicap_data_buffer_t *data_buffer; /* Check if dqbuf will block. If could block indefinitely, hanging the whole application in effect. */ if( !fd_readable( handle->fd ) ) { sem_post( &handle->sema ); continue; } if( !SUCCESS( buffer_mgr_dequeue( handle->buffer_mgr, &data_buffer ) ) ){ TRACE( "buffer_mgr_dequeue failed!\n" ); usleep (1000); continue; } unicap_data_buffer_ref (data_buffer); if( data_buffer->buffer_size < handle->current_format.buffer_size ) { TRACE( "Corrupt frame!\n" ); /* drop = 1; */ } if( !drop && handle->event_callback ) { handle->event_callback( handle->unicap_handle, UNICAP_EVENT_NEW_FRAME, data_buffer ); } unicap_data_buffer_unref( data_buffer ); } } libunicap/cpi/v4l2cpi/v4l2.h0000644000175000017500000001001013164711411016243 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __V4L2_H__ #define __V4L2_H__ #include #include #include #include #include "buffermanager.h" #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #define MAX_V4L2_FORMATS 128 #define V4L2_MAX_VIDEO_INPUTS 32 #define V4L2_MAX_VIDEO_NORMS 32 #define V4L2_MAX_FRAME_RATES 32 #define V4L2_NUM_BUFFERS 16 struct v4l_cache_entry { char devpath[512]; unicap_device_t device; int is_v4l2; int fd; }; enum _cpi_v4l2_io_method_enum { CPI_V4L2_IO_METHOD_UNDECIDED = 0, CPI_V4L2_IO_METHOD_USERPOINTER, CPI_V4L2_IO_METHOD_MMAP, CPI_V4L2_IO_METHOD_READWRITE, }; typedef enum _cpi_v4l2_io_method_enum cpi_v4l2_io_method_enum_t; typedef struct _v4l2_handle *v4l2_handle_t; typedef unicap_status_t (*override_property_func_t) ( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ); struct _cpi_v4l2_buffer { void *start; size_t length; }; struct v4l2_uc_compat { char *driver; int (*probe_func)(v4l2_handle_t handle,const char*path); int (*count_ext_property_func)(v4l2_handle_t handle); unicap_status_t (*enumerate_property_func) ( v4l2_handle_t handle, int index, unicap_property_t *property ); unicap_status_t (*override_property_func) ( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ); unicap_status_t (*set_property_func) ( v4l2_handle_t handle, unicap_property_t *property ); unicap_status_t (*get_property_func) ( v4l2_handle_t handle, unicap_property_t *property ); unicap_status_t (*fmt_get_func) ( struct v4l2_fmtdesc *v4l2fmt, struct v4l2_cropcap *cropcap, char **identifier, unsigned int *fourcc, int *bpp ); unicap_status_t (*override_framesize_func)( v4l2_handle_t handle, struct v4l2_frmsizeenum *frms ); unicap_status_t (*tov4l2format_func)( v4l2_handle_t handle, unicap_format_t *format ); }; struct _v4l2_handle { char device[512]; int fd; char card_name[512]; unicap_format_t *unicap_formats; int format_count; int supported_formats; unicap_format_t current_format; int format_mask[MAX_V4L2_FORMATS]; unicap_property_t *unicap_properties; __u32 *control_ids; int property_count; int video_in_count; int frame_rate_count; char *video_inputs[V4L2_MAX_VIDEO_INPUTS]; char *video_norms[V4L2_MAX_VIDEO_NORMS]; double frame_rates[V4L2_MAX_FRAME_RATES]; int sizes_allocated; buffer_mgr_t buffer_mgr; cpi_v4l2_io_method_enum_t io_method; int buffer_count; struct _cpi_v4l2_buffer *buffers; // for method mmap int *free_buffers; struct _unicap_queue *in_queue; int in_queue_lock; struct _unicap_queue *out_queue; int out_queue_lock; int capture_running; volatile int quit_capture_thread; volatile int dqindex; volatile int qindex; pthread_t capture_thread; sem_t sema; unicap_event_callback_t event_callback; unicap_handle_t unicap_handle; int drop_count; double frame_rate; struct v4l2_uc_compat *compat; int removed; unsigned short pid; }; #endif//__V4L2_H__ libunicap/cpi/v4l2cpi/Makefile.am0000644000175000017500000000153313164711411017351 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in INCLUDES = -I../include -I../../include -I../../common if ENABLE_STATIC_CPI noinst_LTLIBRARIES = libv4l2cpi.la libv4l2cpi_la_LIBADD = @PTHREAD_LIBS@ @LIBV4L_LIBS@ @LIBUDEV_LIBS@ -L../../common -lucutils else libcpi_LTLIBRARIES = libv4l2cpi.la libv4l2cpi_la_LIBADD = @PTHREAD_LIBS@ @LIBV4L_LIBS@ @LIBUDEV_LIBS@ -L../../src/.libs/ -lunicap -L../../common -lucutils endif libcpidir = $(libdir)/unicap$(pkg_version)/cpi libv4l2cpi_la_LDFLAGS = -module -avoid-version libv4l2cpi_la_CFLAGS = @LIBV4L_CFLAGS@ @LIBUDEV_CFLAGS@ libv4l2cpi_la_SOURCES = \ v4l2.c v4l2.h \ buffermanager.c buffermanager.h \ tisuvccam.c tisuvccam.h uvcvideo.h uvc_compat.h \ tiseuvccam.c tiseuvccam.h \ udev.h if HAVE_LIBUDEV libv4l2cpi_la_SOURCES += udev.c else libv4l2cpi_la_SOURCES += udev_stub.c endif EXTRA_DIST = v4l2_i18n_strings.hlibunicap/cpi/v4l2cpi/udev_stub.c0000644000175000017500000000151213164711411017456 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2011 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include char *v4l2cpi_udev_get_serial (const char* devfile) { return NULL; } libunicap/cpi/v4l2cpi/uvc_compat.h0000644000175000017500000001774113164711411017636 0ustar zmoelnigzmoelnig#ifndef _UVC_COMPAT_H #define _UVC_COMPAT_H #include #ifndef __KERNEL__ #ifndef __user #define __user #endif #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) /* * Extended control API */ struct v4l2_ext_control { __u32 id; __u32 reserved2[2]; union { __s32 value; __s64 value64; void *reserved; }; } __attribute__ ((packed)); struct v4l2_ext_controls { __u32 ctrl_class; __u32 count; __u32 error_idx; __u32 reserved[2]; struct v4l2_ext_control *controls; }; /* Values for ctrl_class field */ #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ #define V4L2_CTRL_ID_MASK (0x0fffffff) #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) /* Control flags */ #define V4L2_CTRL_FLAG_READ_ONLY 0x0004 #define V4L2_CTRL_FLAG_UPDATE 0x0008 #define V4L2_CTRL_FLAG_INACTIVE 0x0010 #define V4L2_CTRL_FLAG_SLIDER 0x0020 /* Query flags, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 /* User-class control IDs defined by V4L2 */ #undef V4L2_CID_BASE #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) #define V4L2_CID_USER_BASE V4L2_CID_BASE #define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) /* * Frame size and frame rate enumeration * * Included in Linux 2.6.19 */ enum v4l2_frmsizetypes { V4L2_FRMSIZE_TYPE_DISCRETE = 1, V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, V4L2_FRMSIZE_TYPE_STEPWISE = 3, }; struct v4l2_frmsize_discrete { __u32 width; /* Frame width [pixel] */ __u32 height; /* Frame height [pixel] */ }; struct v4l2_frmsize_stepwise { __u32 min_width; /* Minimum frame width [pixel] */ __u32 max_width; /* Maximum frame width [pixel] */ __u32 step_width; /* Frame width step size [pixel] */ __u32 min_height; /* Minimum frame height [pixel] */ __u32 max_height; /* Maximum frame height [pixel] */ __u32 step_height; /* Frame height step size [pixel] */ }; struct v4l2_frmsizeenum { __u32 index; /* Frame size number */ __u32 pixel_format; /* Pixel format */ __u32 type; /* Frame size type the device supports. */ union { /* Frame size */ struct v4l2_frmsize_discrete discrete; struct v4l2_frmsize_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; enum v4l2_frmivaltypes { V4L2_FRMIVAL_TYPE_DISCRETE = 1, V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, V4L2_FRMIVAL_TYPE_STEPWISE = 3, }; struct v4l2_frmival_stepwise { struct v4l2_fract min; /* Minimum frame interval [s] */ struct v4l2_fract max; /* Maximum frame interval [s] */ struct v4l2_fract step; /* Frame interval step size [s] */ }; struct v4l2_frmivalenum { __u32 index; /* Frame format index */ __u32 pixel_format; /* Pixel format */ __u32 width; /* Frame width */ __u32 height; /* Frame height */ __u32 type; /* Frame interval type the device supports. */ union { /* Frame interval */ struct v4l2_fract discrete; struct v4l2_frmival_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) /* * V4L2 Control identifiers. */ #define V4L2_CTRL_CLASS_CAMERA 0x009A0000 /* Camera class controls */ #define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) enum v4l2_power_line_frequency { V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, }; #define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) #define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) #define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) enum v4l2_exposure_auto_type { V4L2_EXPOSURE_MANUAL = 0, V4L2_EXPOSURE_AUTO = 1, V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, V4L2_EXPOSURE_APERTURE_PRIORITY = 3 }; #define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) #define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) #define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) #define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) #define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) #define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) #define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) #define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) #define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) #define V4L2_CID_PRIVACY_CONTROL (V4L2_CID_CAMERA_CLASS_BASE+13) #endif #ifdef __KERNEL__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) /* * kzalloc() */ static inline void * kzalloc(size_t size, unsigned int __nocast gfp_flags) { void *mem = kmalloc(size, gfp_flags); if (mem) memset(mem, 0, size); return mem; } #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) /* * vm_insert_page() */ static inline int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page *page) { /* Not sure if this is needed. remap_pfn_range() sets VM_RESERVED * in 2.6.14. */ vma->vm_flags |= VM_RESERVED; SetPageReserved(page); return remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot); } #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) /* * v4l_printk_ioctl() */ static inline void v4l_printk_ioctl(unsigned int cmd) { switch (_IOC_TYPE(cmd)) { case 'v': printk(KERN_DEBUG "ioctl 0x%x (V4L1)\n", cmd); break; case 'V': printk(KERN_DEBUG "ioctl 0x%x (%s)\n", cmd, v4l2_ioctl_names[_IOC_NR(cmd)]); break; default: printk(KERN_DEBUG "ioctl 0x%x (?)\n", cmd); break; } } #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) /* * Mutex API */ #include #define mutex_lock(mutex) down(mutex) #define mutex_lock_interruptible(mutex) down_interruptible(mutex) #define mutex_unlock(mutex) up(mutex) #define mutex_init(mutex) init_MUTEX(mutex) #define mutex semaphore #else #include #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) /* * usb_endpoint_* functions * * Included in Linux 2.6.19 */ static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) { return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); } static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) { return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT); } static inline int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd) { return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC); } static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) { return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK); } static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) { return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd)); } /* * USB auto suspend * * Included in Linux 2.6.19 */ static inline int usb_autopm_get_interface(struct usb_interface *intf) { return 0; } static inline void usb_autopm_put_interface(struct usb_interface *intf) { } #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) /* * Linked list API */ #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #endif #endif /* __KERNEL__ */ #endif /* _UVC_COMPAT_H */ libunicap/cpi/v4l2cpi/v4l2_i18n_strings.h0000644000175000017500000000156413164711411020671 0ustar zmoelnigzmoelnig/* ** v4l2_i18n_strings.h ** ** Made by Arne Caspari ** Login ** ** Started on Wed Sep 5 18:11:42 2007 Arne Caspari ** Last update Wed Sep 5 18:11:42 2007 Arne Caspari */ #ifndef V4L2_I18N_STRINGS_H_ # define V4L2_I18N_STRINGS_H_ N_("anti-flicking"); N_("auto exposure/gain"); N_("auto white balance"); N_("Brightness"); N_("brightness"); N_("Contrast"); N_("contrast"); N_("Exposure, Auto"); N_("frame rate"); N_("Gain"); N_("gain"); N_("Gamma"); N_("gamma"); N_("horizontal flip"); N_("Hue"); N_("hue"); N_("Power Line Frequency"); N_("resolution"); N_("Saturation"); N_("saturation"); N_("Sharpness"); N_("sharpness"); N_("Shutter"); N_("shutter"); N_("vertical flip"); N_("video source"); N_("White Balance Temperature, Auto"); N_("White Balance Temperature"); N_("YUV 4:2:2 (YUYV)"); N_("Uncompressed"); #endif /* !V4L2_I18N_STRINGS_H_ */ libunicap/cpi/v4l2cpi/buffermanager.c0000644000175000017500000001562613164711411020275 0ustar zmoelnigzmoelnig#include "config.h" #include #include #include #include #include #include #include #include #if V4L2_DEBUG #define DEBUG #endif #include "debug.h" #include "buffermanager.h" #define MAX_BUFFERS 16 #if USE_LIBV4L #define OPEN v4l2_open #define CLOSE v4l2_close #define IOCTL v4l2_ioctl #define MMAP v4l2_mmap #define MUNMAP v4l2_munmap #else #define OPEN open #define CLOSE close #define IOCTL ioctl #define MMAP mmap #define MUNMAP munmap #endif struct v4l2cpi_buffer { struct v4l2_buffer v4l2_buffer; unicap_data_buffer_t data_buffer; int refcount; int queued; void *start; size_t length; }; typedef struct v4l2cpi_buffer v4l2cpi_buffer_t; struct buffer_mgr { v4l2cpi_buffer_t buffers[ MAX_BUFFERS ]; int free_buffers; int num_buffers; sem_t lock; int fd; }; #define BUFFER_MGR_LOCK(mgr) { sem_wait( &mgr->lock ); } #define BUFFER_MGR_UNLOCK(mgr) { sem_post( &mgr->lock); } static v4l2cpi_buffer_t *buffer_mgr_get_cpi_buffer( buffer_mgr_t mgr, unicap_data_buffer_t *buffer ); static void v4l2_data_buffer_unref( unicap_data_buffer_t *buffer, buffer_mgr_t mgr ) { if (unicap_data_buffer_get_refcount( buffer ) == 1 ){ buffer_mgr_queue (mgr, buffer); } } buffer_mgr_t buffer_mgr_create( int fd, unicap_format_t *format ) { buffer_mgr_t mgr = malloc( sizeof( struct buffer_mgr ) ); int i; unicap_data_buffer_init_data_t init_data = { NULL, NULL, NULL, NULL, (unicap_data_buffer_func_t)v4l2_data_buffer_unref, mgr }; memset( mgr, 0x0, sizeof( buffer_mgr_t ) ); if( sem_init( &mgr->lock, 0, 1 ) ){ TRACE( "sem_init failed\n" ); free( mgr ); return NULL; } mgr->fd = fd; struct v4l2_requestbuffers v4l2_reqbuf; memset( &v4l2_reqbuf, 0x0, sizeof( struct v4l2_requestbuffers ) ); v4l2_reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_reqbuf.memory = V4L2_MEMORY_MMAP; v4l2_reqbuf.count = MAX_BUFFERS; if( IOCTL( fd, VIDIOC_REQBUFS, &v4l2_reqbuf ) < 0 ) { TRACE( "VIDIOC_REQBUFS failed: %s\n", strerror( errno ) ); return NULL; } mgr->num_buffers = v4l2_reqbuf.count; for( i = 0; i < v4l2_reqbuf.count; i++ ){ memset( &mgr->buffers[i], 0x0, sizeof( v4l2cpi_buffer_t ) ); unicap_data_buffer_init (&mgr->buffers[i].data_buffer, format, &init_data); unicap_data_buffer_ref (&mgr->buffers[i].data_buffer); mgr->buffers[i].v4l2_buffer.type = v4l2_reqbuf.type; mgr->buffers[i].v4l2_buffer.memory = V4L2_MEMORY_MMAP; mgr->buffers[i].v4l2_buffer.index = i; if( IOCTL( mgr->fd, VIDIOC_QUERYBUF, &mgr->buffers[i].v4l2_buffer ) < 0 ){ TRACE( "VIDIOC_QUERYBUF ioctl failed: %s, index = %d\n", strerror( errno ), i ); // TODO: Cleanup return NULL; } mgr->buffers[i].length = mgr->buffers[i].v4l2_buffer.length; mgr->buffers[i].start = MMAP( NULL, mgr->buffers[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mgr->buffers[i].v4l2_buffer.m.offset ); if( mgr->buffers[i].start == MAP_FAILED ){ TRACE( "MMAP Failed: %s, index = %d\n", strerror( errno ), i ); // TODO: Cleanup return NULL; } mgr->buffers[i].data_buffer.buffer_size = mgr->buffers[i].v4l2_buffer.length; mgr->buffers[i].data_buffer.data = mgr->buffers[i].start; mgr->free_buffers++; } return mgr; } void buffer_mgr_destroy( buffer_mgr_t mgr ) { int i; BUFFER_MGR_LOCK( mgr ); for (i = 0; i < mgr->num_buffers; i++ ){ MUNMAP( mgr->buffers[i].start, mgr->buffers[i].length ); } struct v4l2_requestbuffers v4l2_reqbuf; memset( &v4l2_reqbuf, 0x0, sizeof( struct v4l2_requestbuffers ) ); v4l2_reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_reqbuf.memory = V4L2_MEMORY_MMAP; v4l2_reqbuf.count = 0; if( IOCTL( mgr->fd, VIDIOC_REQBUFS, &v4l2_reqbuf ) < 0 ) { TRACE( "VIDIOC_REQBUFS failed: %s\n", strerror( errno ) ); } sem_destroy (&mgr->lock); free (mgr); } static v4l2cpi_buffer_t *buffer_mgr_get_cpi_buffer( buffer_mgr_t mgr, unicap_data_buffer_t *buffer ) { int i; for( i = 0; i < mgr->num_buffers; i++ ){ if (&mgr->buffers[i].data_buffer == buffer){ return &mgr->buffers[i]; } } return NULL; } unicap_status_t buffer_mgr_queue_all( buffer_mgr_t mgr ) { int i; unicap_status_t status = STATUS_SUCCESS; for( i = 0; i < mgr->num_buffers; i++ ){ unicap_status_t tmp; if( !SUCCESS( tmp = buffer_mgr_queue( mgr, &mgr->buffers[i].data_buffer ) ) ){ status = tmp; } } return status; } unicap_status_t buffer_mgr_queue( buffer_mgr_t mgr, unicap_data_buffer_t *buffer ) { int i; unicap_status_t status = STATUS_INVALID_PARAMETER; BUFFER_MGR_LOCK( mgr ); for( i = 0; i < mgr->num_buffers; i++ ){ if (&mgr->buffers[i].data_buffer == buffer){ int ret; if( ( ret = IOCTL( mgr->fd, VIDIOC_QBUF, &mgr->buffers[i].v4l2_buffer ) ) < 0 ){ if( ret == -ENODEV ){ status = STATUS_NO_DEVICE; } TRACE( "VIDIOC_QBUF ioctl failed: %s\n", strerror( errno ) ); } else { status = STATUS_SUCCESS; mgr->buffers[i].queued = 1; } break; } } BUFFER_MGR_UNLOCK( mgr ); return status; } unicap_status_t buffer_mgr_dequeue( buffer_mgr_t mgr, unicap_data_buffer_t **buffer ) { struct v4l2_buffer v4l2_buffer; unicap_status_t status = STATUS_SUCCESS; int i; *buffer = NULL; memset (&v4l2_buffer, 0x0, sizeof (v4l2_buffer)); v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.memory = V4L2_MEMORY_MMAP; BUFFER_MGR_LOCK (mgr); if( IOCTL( mgr->fd, VIDIOC_DQBUF, &v4l2_buffer ) < 0 ){ TRACE( "VIDIOC_DQBUF ioctl failed: %s\n", strerror( errno ) ); status = STATUS_FAILURE; } else { for (i = 0; i < mgr->num_buffers; i++ ){ if (mgr->buffers[i].v4l2_buffer.index == v4l2_buffer.index ){ mgr->buffers[i].queued = 0; mgr->buffers[i].data_buffer.buffer_size = v4l2_buffer.bytesused; memcpy( &mgr->buffers[i].data_buffer.fill_time, &v4l2_buffer.timestamp, sizeof( struct timeval ) ); *buffer = &mgr->buffers[i].data_buffer; break; } } } if (!*buffer){ TRACE ("VIDIOC_DQBUF returned a buffer that is not in the pool (%d) !?!?!?", v4l2_buffer.index ); status = STATUS_FAILURE; } BUFFER_MGR_UNLOCK (mgr); return status; } unicap_status_t buffer_mgr_dequeue_all (buffer_mgr_t mgr ) { int i; unicap_status_t status = STATUS_SUCCESS; BUFFER_MGR_LOCK (mgr); for (i=0; i < mgr->num_buffers; i++){ if (mgr->buffers[i].queued){ if( IOCTL( mgr->fd, VIDIOC_DQBUF, &mgr->buffers[i].v4l2_buffer ) < 0 ){ TRACE( "VIDIOC_DQBUF ioctl failed: %s\n", strerror( errno ) ); status = STATUS_FAILURE; } else { mgr->buffers[i].queued = 0; } } } BUFFER_MGR_UNLOCK (mgr); return status; } libunicap/cpi/v4l2cpi/udev.c0000644000175000017500000000360613164711411016427 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2011 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include char *v4l2cpi_udev_get_serial (const char* devfile) { struct udev *udev; struct udev_enumerate *enumerate; struct udev_list_entry *devices, *dev_list_entry; struct udev_device *dev; char *ret = NULL; udev = udev_new (); if (!udev) return NULL; enumerate = udev_enumerate_new (udev); udev_enumerate_add_match_subsystem (enumerate, "video4linux"); udev_enumerate_scan_devices (enumerate); devices = udev_enumerate_get_list_entry (enumerate); udev_list_entry_foreach (dev_list_entry, devices){ const char *path; path = udev_list_entry_get_name (dev_list_entry); dev = udev_device_new_from_syspath (udev, path); if (!strcmp (udev_device_get_devnode (dev), devfile)){ dev = udev_device_get_parent_with_subsystem_devtype (dev, "usb", "usb_device"); if (dev){ const char *serial; serial = udev_device_get_sysattr_value(dev, "serial"); if (serial){ ret = malloc (strlen (serial)+1); strcpy (ret, serial); } udev_device_unref (dev); } } } /* Free the enumerator object */ udev_enumerate_unref(enumerate); udev_unref(udev); return ret; } libunicap/cpi/v4l2cpi/buffermanager.h0000644000175000017500000000114713164711411020273 0ustar zmoelnigzmoelnig#ifndef __BUFERMGR_H__ #define __BUFERMGR_H__ #include #include #include #include typedef struct buffer_mgr *buffer_mgr_t; buffer_mgr_t buffer_mgr_create( int fd, unicap_format_t *format ); void buffer_mgr_destroy( buffer_mgr_t mgr ); unicap_status_t buffer_mgr_queue_all( buffer_mgr_t mgr ); unicap_status_t buffer_mgr_queue( buffer_mgr_t mgr, unicap_data_buffer_t *buffer ); unicap_status_t buffer_mgr_dequeue( buffer_mgr_t mgr, unicap_data_buffer_t **buffer ); unicap_status_t buffer_mgr_dequeue_all (buffer_mgr_t mgr ); #endif//__BUFERMGR_H__ libunicap/cpi/v4l2cpi/uvcvideo.h0000644000175000017500000005471213164711411017321 0ustar zmoelnigzmoelnig#ifndef _USB_VIDEO_H_ #define _USB_VIDEO_H_ #include #include #include "uvc_compat.h" /* * Dynamic controls */ /* Data types for UVC control data */ enum uvc_control_data_type { UVC_CTRL_DATA_TYPE_RAW = 0, UVC_CTRL_DATA_TYPE_SIGNED, UVC_CTRL_DATA_TYPE_UNSIGNED, UVC_CTRL_DATA_TYPE_BOOLEAN, UVC_CTRL_DATA_TYPE_ENUM, UVC_CTRL_DATA_TYPE_BITMASK, }; #define UVC_CONTROL_SET_CUR (1 << 0) #define UVC_CONTROL_GET_CUR (1 << 1) #define UVC_CONTROL_GET_MIN (1 << 2) #define UVC_CONTROL_GET_MAX (1 << 3) #define UVC_CONTROL_GET_RES (1 << 4) #define UVC_CONTROL_GET_DEF (1 << 5) /* Control should be saved at suspend and restored at resume. */ #define UVC_CONTROL_RESTORE (1 << 6) /* Control can be updated by the camera. */ #define UVC_CONTROL_AUTO_UPDATE (1 << 7) #define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ UVC_CONTROL_GET_DEF) struct uvc_xu_control_info { __u8 entity[16]; __u8 index; __u8 selector; __u16 size; __u32 flags; }; struct uvc_xu_control_mapping { __u32 id; __u8 name[32]; __u8 entity[16]; __u8 selector; __u8 size; __u8 offset; enum v4l2_ctrl_type v4l2_type; enum uvc_control_data_type data_type; }; struct uvc_xu_control { __u8 unit; __u8 selector; __u16 size; __u8 __user *data; }; #define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) #define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) #define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) #define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) #ifdef __KERNEL__ #include /* -------------------------------------------------------------------------- * UVC constants */ #define SC_UNDEFINED 0x00 #define SC_VIDEOCONTROL 0x01 #define SC_VIDEOSTREAMING 0x02 #define SC_VIDEO_INTERFACE_COLLECTION 0x03 #define PC_PROTOCOL_UNDEFINED 0x00 #define CS_UNDEFINED 0x20 #define CS_DEVICE 0x21 #define CS_CONFIGURATION 0x22 #define CS_STRING 0x23 #define CS_INTERFACE 0x24 #define CS_ENDPOINT 0x25 /* VideoControl class specific interface descriptor */ #define VC_DESCRIPTOR_UNDEFINED 0x00 #define VC_HEADER 0x01 #define VC_INPUT_TERMINAL 0x02 #define VC_OUTPUT_TERMINAL 0x03 #define VC_SELECTOR_UNIT 0x04 #define VC_PROCESSING_UNIT 0x05 #define VC_EXTENSION_UNIT 0x06 /* VideoStreaming class specific interface descriptor */ #define VS_UNDEFINED 0x00 #define VS_INPUT_HEADER 0x01 #define VS_OUTPUT_HEADER 0x02 #define VS_STILL_IMAGE_FRAME 0x03 #define VS_FORMAT_UNCOMPRESSED 0x04 #define VS_FRAME_UNCOMPRESSED 0x05 #define VS_FORMAT_MJPEG 0x06 #define VS_FRAME_MJPEG 0x07 #define VS_FORMAT_MPEG2TS 0x0a #define VS_FORMAT_DV 0x0c #define VS_COLORFORMAT 0x0d #define VS_FORMAT_FRAME_BASED 0x10 #define VS_FRAME_FRAME_BASED 0x11 #define VS_FORMAT_STREAM_BASED 0x12 /* Endpoint type */ #define EP_UNDEFINED 0x00 #define EP_GENERAL 0x01 #define EP_ENDPOINT 0x02 #define EP_INTERRUPT 0x03 /* Request codes */ #define RC_UNDEFINED 0x00 #define SET_CUR 0x01 #define GET_CUR 0x81 #define GET_MIN 0x82 #define GET_MAX 0x83 #define GET_RES 0x84 #define GET_LEN 0x85 #define GET_INFO 0x86 #define GET_DEF 0x87 /* VideoControl interface controls */ #define VC_CONTROL_UNDEFINED 0x00 #define VC_VIDEO_POWER_MODE_CONTROL 0x01 #define VC_REQUEST_ERROR_CODE_CONTROL 0x02 /* Terminal controls */ #define TE_CONTROL_UNDEFINED 0x00 /* Selector Unit controls */ #define SU_CONTROL_UNDEFINED 0x00 #define SU_INPUT_SELECT_CONTROL 0x01 /* Camera Terminal controls */ #define CT_CONTROL_UNDEFINED 0x00 #define CT_SCANNING_MODE_CONTROL 0x01 #define CT_AE_MODE_CONTROL 0x02 #define CT_AE_PRIORITY_CONTROL 0x03 #define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 #define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 #define CT_FOCUS_ABSOLUTE_CONTROL 0x06 #define CT_FOCUS_RELATIVE_CONTROL 0x07 #define CT_FOCUS_AUTO_CONTROL 0x08 #define CT_IRIS_ABSOLUTE_CONTROL 0x09 #define CT_IRIS_RELATIVE_CONTROL 0x0a #define CT_ZOOM_ABSOLUTE_CONTROL 0x0b #define CT_ZOOM_RELATIVE_CONTROL 0x0c #define CT_PANTILT_ABSOLUTE_CONTROL 0x0d #define CT_PANTILT_RELATIVE_CONTROL 0x0e #define CT_ROLL_ABSOLUTE_CONTROL 0x0f #define CT_ROLL_RELATIVE_CONTROL 0x10 #define CT_PRIVACY_CONTROL 0x11 /* Processing Unit controls */ #define PU_CONTROL_UNDEFINED 0x00 #define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 #define PU_BRIGHTNESS_CONTROL 0x02 #define PU_CONTRAST_CONTROL 0x03 #define PU_GAIN_CONTROL 0x04 #define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 #define PU_HUE_CONTROL 0x06 #define PU_SATURATION_CONTROL 0x07 #define PU_SHARPNESS_CONTROL 0x08 #define PU_GAMMA_CONTROL 0x09 #define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a #define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b #define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c #define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d #define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e #define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f #define PU_HUE_AUTO_CONTROL 0x10 #define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 #define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 #define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01 #define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02 #define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03 /* VideoStreaming interface controls */ #define VS_CONTROL_UNDEFINED 0x00 #define VS_PROBE_CONTROL 0x01 #define VS_COMMIT_CONTROL 0x02 #define VS_STILL_PROBE_CONTROL 0x03 #define VS_STILL_COMMIT_CONTROL 0x04 #define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 #define VS_STREAM_ERROR_CODE_CONTROL 0x06 #define VS_GENERATE_KEY_FRAME_CONTROL 0x07 #define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 #define VS_SYNC_DELAY_CONTROL 0x09 #define TT_VENDOR_SPECIFIC 0x0100 #define TT_STREAMING 0x0101 /* Input Terminal types */ #define ITT_VENDOR_SPECIFIC 0x0200 #define ITT_CAMERA 0x0201 #define ITT_MEDIA_TRANSPORT_INPUT 0x0202 /* Output Terminal types */ #define OTT_VENDOR_SPECIFIC 0x0300 #define OTT_DISPLAY 0x0301 #define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 /* External Terminal types */ #define EXTERNAL_VENDOR_SPECIFIC 0x0400 #define COMPOSITE_CONNECTOR 0x0401 #define SVIDEO_CONNECTOR 0x0402 #define COMPONENT_CONNECTOR 0x0403 #define UVC_TERM_INPUT 0x0000 #define UVC_TERM_OUTPUT 0x8000 #define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) #define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) #define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0) #define UVC_ENTITY_IS_ITERM(entity) \ (((entity)->type & 0x8000) == UVC_TERM_INPUT) #define UVC_ENTITY_IS_OTERM(entity) \ (((entity)->type & 0x8000) == UVC_TERM_OUTPUT) #define UVC_STATUS_TYPE_CONTROL 1 #define UVC_STATUS_TYPE_STREAMING 2 /* ------------------------------------------------------------------------ * GUIDs */ #define UVC_GUID_UVC_CAMERA \ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} #define UVC_GUID_UVC_OUTPUT \ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02} #define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03} #define UVC_GUID_UVC_PROCESSING \ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01} #define UVC_GUID_UVC_SELECTOR \ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02} #define UVC_GUID_LOGITECH_DEV_INFO \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e} #define UVC_GUID_LOGITECH_USER_HW \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f} #define UVC_GUID_LOGITECH_VIDEO \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50} #define UVC_GUID_LOGITECH_MOTOR \ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56} #define UVC_GUID_FORMAT_MJPEG \ { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_YUY2 \ { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_NV12 \ { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_YV12 \ { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_I420 \ { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_UYVY \ { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_Y800 \ { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_BY8 \ { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} /* ------------------------------------------------------------------------ * Driver specific constants. */ #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) /* Number of isochronous URBs. */ #define UVC_URBS 5 /* Maximum number of packets per isochronous URB. */ #define UVC_MAX_ISO_PACKETS 40 /* Maximum frame size in bytes, for sanity checking. */ #define UVC_MAX_FRAME_SIZE (16*1024*1024) /* Maximum number of video buffers. */ #define UVC_MAX_VIDEO_BUFFERS 32 #define UVC_CTRL_CONTROL_TIMEOUT 300 #define UVC_CTRL_STREAMING_TIMEOUT 1000 /* Devices quirks */ #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 #define UVC_QUIRK_PROBE_MINMAX 0x00000002 #define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004 #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 #define UVC_QUIRK_STREAM_NO_FID 0x00000010 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 #define UVC_FMT_FLAG_STREAM 0x00000002 /* ------------------------------------------------------------------------ * Structures. */ struct uvc_device; /* TODO: Put the most frequently accessed fields at the beginning of * structures to maximize cache efficiency. */ struct uvc_streaming_control { __u16 bmHint; __u8 bFormatIndex; __u8 bFrameIndex; __u32 dwFrameInterval; __u16 wKeyFrameRate; __u16 wPFrameRate; __u16 wCompQuality; __u16 wCompWindowSize; __u16 wDelay; __u32 dwMaxVideoFrameSize; __u32 dwMaxPayloadTransferSize; __u32 dwClockFrequency; __u8 bmFramingInfo; __u8 bPreferedVersion; __u8 bMinVersion; __u8 bMaxVersion; }; struct uvc_menu_info { __u32 value; __u8 name[32]; }; struct uvc_control_info { struct list_head list; struct list_head mappings; __u8 entity[16]; __u8 index; __u8 selector; __u16 size; __u32 flags; }; struct uvc_control_mapping { struct list_head list; struct uvc_control_info *ctrl; __u32 id; __u8 name[32]; __u8 entity[16]; __u8 selector; __u8 size; __u8 offset; enum v4l2_ctrl_type v4l2_type; enum uvc_control_data_type data_type; struct uvc_menu_info *menu_info; __u32 menu_count; }; struct uvc_control { struct uvc_entity *entity; struct uvc_control_info *info; __u8 index; /* Used to match the uvc_control entry with a uvc_control_info. */ __u8 dirty : 1, loaded : 1, modified : 1; __u8 *data; }; struct uvc_format_desc { char *name; __u8 guid[16]; __u32 fcc; }; /* The term 'entity' refers to both UVC units and UVC terminals. * * The type field is either the terminal type (wTerminalType in the terminal * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor). * As the bDescriptorSubtype field is one byte long, the type value will * always have a null MSB for units. All terminal types defined by the UVC * specification have a non-null MSB, so it is safe to use the MSB to * differentiate between units and terminals as long as the descriptor parsing * code makes sure terminal types have a non-null MSB. * * For terminals, the type's most significant bit stores the terminal * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should * always be accessed with the UVC_ENTITY_* macros and never directly. */ struct uvc_entity { struct list_head list; /* Entity as part of a UVC device. */ struct list_head chain; /* Entity as part of a video device * chain. */ __u8 id; __u16 type; char name[64]; union { struct { __u16 wObjectiveFocalLengthMin; __u16 wObjectiveFocalLengthMax; __u16 wOcularFocalLength; __u8 bControlSize; __u8 *bmControls; } camera; struct { __u8 bControlSize; __u8 *bmControls; __u8 bTransportModeSize; __u8 *bmTransportModes; } media; struct { __u8 bSourceID; } output; struct { __u8 bSourceID; __u16 wMaxMultiplier; __u8 bControlSize; __u8 *bmControls; __u8 bmVideoStandards; } processing; struct { __u8 bNrInPins; __u8 *baSourceID; } selector; struct { __u8 guidExtensionCode[16]; __u8 bNumControls; __u8 bNrInPins; __u8 *baSourceID; __u8 bControlSize; __u8 *bmControls; __u8 *bmControlsType; } extension; }; unsigned int ncontrols; struct uvc_control *controls; }; struct uvc_frame { __u8 bFrameIndex; __u8 bmCapabilities; __u16 wWidth; __u16 wHeight; __u32 dwMinBitRate; __u32 dwMaxBitRate; __u32 dwMaxVideoFrameBufferSize; __u8 bFrameIntervalType; __u32 dwDefaultFrameInterval; __u32 *dwFrameInterval; }; struct uvc_format { __u8 type; __u8 index; __u8 bpp; __u8 colorspace; __u32 fcc; __u32 flags; char name[32]; unsigned int nframes; struct uvc_frame *frame; }; struct uvc_streaming_header { __u8 bNumFormats; __u8 bEndpointAddress; __u8 bTerminalLink; __u8 bControlSize; __u8 *bmaControls; /* The following fields are used by input headers only. */ __u8 bmInfo; __u8 bStillCaptureMethod; __u8 bTriggerSupport; __u8 bTriggerUsage; }; struct uvc_streaming { struct list_head list; struct usb_interface *intf; int intfnum; __u16 maxpsize; struct uvc_streaming_header header; unsigned int nformats; struct uvc_format *format; struct uvc_streaming_control ctrl; struct uvc_format *cur_format; struct uvc_frame *cur_frame; struct mutex mutex; }; enum uvc_buffer_state { UVC_BUF_STATE_IDLE = 0, UVC_BUF_STATE_QUEUED = 1, UVC_BUF_STATE_ACTIVE = 2, UVC_BUF_STATE_DONE = 3, UVC_BUF_STATE_ERROR = 4, }; struct uvc_buffer { unsigned long vma_use_count; struct list_head stream; /* Touched by interrupt handler. */ struct v4l2_buffer buf; struct list_head queue; wait_queue_head_t wait; enum uvc_buffer_state state; }; struct uvc_video_queue { void *mem; unsigned int streaming : 1, frozen : 1; __u32 sequence; unsigned int count; unsigned int buf_size; struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; struct mutex mutex; /* protects buffers and mainqueue */ spinlock_t irqlock; /* protects irqqueue */ struct list_head mainqueue; struct list_head irqqueue; }; struct uvc_video_device { struct uvc_device *dev; struct video_device *vdev; atomic_t active; struct list_head iterms; struct uvc_entity *oterm; struct uvc_entity *processing; struct uvc_entity *selector; struct list_head extensions; struct mutex ctrl_mutex; struct uvc_video_queue queue; /* Video streaming object, must always be non-NULL. */ struct uvc_streaming *streaming; void (*decode) (struct urb *urb, struct uvc_video_device *video, struct uvc_buffer *buf); /* Context data used by the bulk completion handler. */ struct { __u8 header[256]; unsigned int header_size; int skip_payload; __u32 payload_size; __u32 max_payload_size; } bulk; struct urb *urb[UVC_URBS]; char *urb_buffer[UVC_URBS]; __u8 last_fid; }; enum uvc_device_state { UVC_DEV_DISCONNECTED = 1, }; struct uvc_device { struct usb_device *udev; struct usb_interface *intf; __u32 quirks; int intfnum; char name[32]; enum uvc_device_state state; struct kref kref; struct list_head list; /* Video control interface */ __u16 uvc_version; __u32 clock_frequency; struct list_head entities; struct uvc_video_device video; /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; __u8 status[16]; struct input_dev *input; /* Video Streaming interfaces */ struct list_head streaming; }; enum uvc_handle_state { UVC_HANDLE_PASSIVE = 0, UVC_HANDLE_ACTIVE = 1, }; struct uvc_fh { struct uvc_video_device *device; enum uvc_handle_state state; }; struct uvc_driver { struct usb_driver driver; struct mutex open_mutex; /* protects from open/disconnect race */ struct list_head devices; /* struct uvc_device list */ struct list_head controls; /* struct uvc_control_info list */ struct mutex ctrl_mutex; /* protects controls and devices lists */ }; /* ------------------------------------------------------------------------ * Debugging, printing and logging */ #define UVC_TRACE_PROBE (1 << 0) #define UVC_TRACE_DESCR (1 << 1) #define UVC_TRACE_CONTROL (1 << 2) #define UVC_TRACE_FORMAT (1 << 3) #define UVC_TRACE_CAPTURE (1 << 4) #define UVC_TRACE_CALLS (1 << 5) #define UVC_TRACE_IOCTL (1 << 6) #define UVC_TRACE_FRAME (1 << 7) #define UVC_TRACE_SUSPEND (1 << 8) #define UVC_TRACE_STATUS (1 << 9) extern unsigned int uvc_trace_param; #define uvc_trace(flag, msg...) \ do { \ if (uvc_trace_param & flag) \ printk(KERN_DEBUG "uvcvideo: " msg); \ } while (0) #define uvc_printk(level, msg...) \ printk(level "uvcvideo: " msg) #define UVC_GUID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \ "%02x%02x%02x%02x%02x%02x" #define UVC_GUID_ARGS(guid) \ (guid)[3], (guid)[2], (guid)[1], (guid)[0], \ (guid)[5], (guid)[4], \ (guid)[7], (guid)[6], \ (guid)[8], (guid)[9], \ (guid)[10], (guid)[11], (guid)[12], \ (guid)[13], (guid)[14], (guid)[15] /* -------------------------------------------------------------------------- * Internal functions. */ /* Core driver */ extern struct uvc_driver uvc_driver; extern void uvc_delete(struct kref *kref); /* Video buffers queue management. */ extern void uvc_queue_init(struct uvc_video_queue *queue); extern int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, unsigned int buflength); extern int uvc_free_buffers(struct uvc_video_queue *queue); extern int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); extern int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf, int nonblocking); extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); extern void uvc_queue_cancel(struct uvc_video_queue *queue); extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, poll_table *wait); /* V4L2 interface */ extern struct file_operations uvc_fops; /* Video */ extern int uvc_video_init(struct uvc_video_device *video); extern int uvc_video_suspend(struct uvc_video_device *video); extern int uvc_video_resume(struct uvc_video_device *video); extern int uvc_video_enable(struct uvc_video_device *video, int enable); extern int uvc_probe_video(struct uvc_video_device *video, struct uvc_streaming_control *probe); extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, __u8 intfnum, __u8 cs, void *data, __u16 size); extern int uvc_set_video_ctrl(struct uvc_video_device *video, struct uvc_streaming_control *ctrl, int probe); /* Status */ extern int uvc_status_init(struct uvc_device *dev); extern void uvc_status_cleanup(struct uvc_device *dev); extern int uvc_status_suspend(struct uvc_device *dev); extern int uvc_status_resume(struct uvc_device *dev); /* Controls */ extern struct uvc_control *uvc_find_control(struct uvc_video_device *video, __u32 v4l2_id, struct uvc_control_mapping **mapping); extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video, struct v4l2_queryctrl *v4l2_ctrl); extern int uvc_ctrl_add_info(struct uvc_control_info *info); extern int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping); extern int uvc_ctrl_init_device(struct uvc_device *dev); extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); extern int uvc_ctrl_resume_device(struct uvc_device *dev); extern void uvc_ctrl_init(void); extern int uvc_ctrl_begin(struct uvc_video_device *video); extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback); static inline int uvc_ctrl_commit(struct uvc_video_device *video) { return __uvc_ctrl_commit(video, 0); } static inline int uvc_ctrl_rollback(struct uvc_video_device *video) { return __uvc_ctrl_commit(video, 1); } extern int uvc_ctrl_get(struct uvc_video_device *video, struct v4l2_ext_control *xctrl); extern int uvc_ctrl_set(struct uvc_video_device *video, struct v4l2_ext_control *xctrl); extern int uvc_xu_ctrl_query(struct uvc_video_device *video, struct uvc_xu_control *ctrl, int set); /* Utility functions */ extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, unsigned int n_terms, unsigned int threshold); extern uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator); extern struct usb_host_endpoint *uvc_find_endpoint( struct usb_host_interface *alts, __u8 epaddr); /* Quirks support */ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, struct uvc_buffer *buf); #endif /* __KERNEL__ */ #endif libunicap/cpi/v4l2cpi/tisuvccam.h0000644000175000017500000000212013164711411017455 0ustar zmoelnigzmoelnig/* ** tisuvccam.h ** ** Made by Arne Caspari ** Login ** ** Started on Tue Jan 8 07:23:05 2008 Arne Caspari ** Last update Tue Jan 8 07:23:05 2008 Arne Caspari */ #ifndef TISUVCCAM_H_ # define TISUVCCAM_H_ #include #include #include #include #include #include "v4l2.h" int tisuvccam_probe( v4l2_handle_t handle, const char *path ); int tisuvccam_count_ext_property( v4l2_handle_t handle ); unicap_status_t tisuvccam_override_property( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ); unicap_status_t tisuvccam_enumerate_properties( v4l2_handle_t handle, int index, unicap_property_t *property ); unicap_status_t tisuvccam_set_property( v4l2_handle_t handle, unicap_property_t *property ); unicap_status_t tisuvccam_get_property( v4l2_handle_t handle, unicap_property_t *property ); unicap_status_t tisuvccam_fmt_get( struct v4l2_fmtdesc *v4l2fmt, struct v4l2_cropcap *cropcap, char **identifier, unsigned int *fourcc, int *bpp ); #endif /* !TISUVCCAM_H_ */ libunicap/cpi/v4l2cpi/tiseuvccam.c0000644000175000017500000004227313164711411017632 0ustar zmoelnigzmoelnig/* ** tiseuvccam.c ** ** Made by (Arne Caspari) ** Login ** ** Started on Thu Jun 5 14:33:13 2008 Arne Caspari */ #include "config.h" #include "tiseuvccam.h" #include #include #include #include #include #include #include #include #include #include #include "uvc_compat.h" #if V4L2_DEBUG #define DEBUG #endif #define TRUE 1 #include "debug.h" #define N_(x) x #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #if USE_LIBV4L #define OPEN v4l2_open #define CLOSE v4l2_close #define IOCTL v4l2_ioctl #define MMAP v4l2_mmap #define MUNMAP v4l2_munmap #else #define OPEN open #define CLOSE close #define IOCTL ioctl #define MMAP mmap #define MUNMAP munmap #endif #define V4L2_CID_EUVC_REGISTER 0x00980926 static double frame_rates[] = { 60.0, 30.0, 25.0, 15.0, 7.5 }; static int frame_rate_register_values[] = { 6, 0, 1, 2, 3 }; static int get_usb_ids( const char *path, unsigned short *vid, unsigned short *pid ) { char respath[PATH_MAX]; char *basen; char prodidpath[PATH_MAX]; char vendidpath[PATH_MAX]; char devicepath[PATH_MAX]; char tmp[PATH_MAX]; FILE *f; strcpy( tmp, path ); basen = basename( tmp ); sprintf( devicepath, "/sys/class/video4linux/%s/device", basen ); if( !realpath( devicepath, respath ) ) { TRACE( "could not resolve path '%s'\n", devicepath ); return 0; } strcpy( vendidpath, devicepath ); strcat( vendidpath, "/../idVendor" ); f = fopen( vendidpath, "r" ); if( !f ) { TRACE( "could not open '%s'\n", vendidpath ); return 0; } else { char buf[5]; memset( buf, 0x0, sizeof( buf ) ); if( fscanf( f, "%hx", vid ) < 1 ) { vid = 0; } fclose( f ); } strcpy( prodidpath, devicepath ); strcat( prodidpath, "/../idProduct" ); f = fopen( prodidpath, "r" ); if( !f ) { TRACE( "could not open '%s'\n", prodidpath ); return 0; } else { char buf[5]; memset( buf, 0x0, sizeof( buf ) ); if( fscanf( f, "%hx", pid ) < 1 ) { pid = 0; } fclose( f ); } return 1; } int tiseuvccam_probe( v4l2_handle_t handle, const char *path ) { int ret = 0; unsigned short vid, pid; get_usb_ids( path, &vid, &pid ); handle->pid = pid; if( ( vid == 0x199e ) && ( ( pid == 0x8201 ) || ( pid == 0x8202 ) || ( pid == 0x8203 ) || ( pid == 0x8204 ) ) ) { TRACE( "Found TIS EUVCCAM\n" ); ret = 1; } return ret; } int tiseuvccam_count_ext_property( v4l2_handle_t handle ) { return 1; } unicap_status_t tiseuvccam_enumerate_properties( v4l2_handle_t handle, int index, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; switch( index ) { case 0: { struct v4l2_control ctrl; strcpy( property->identifier, "sharpness register" ); strcpy( property->category, "debug" ); memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EUVC_REGISTER; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { // XU control not added to the driver return STATUS_NO_MATCH; } property->type = UNICAP_PROPERTY_TYPE_RANGE; property->flags_mask = UNICAP_FLAGS_MANUAL; property->flags = UNICAP_FLAGS_MANUAL; property->value = 0; property->range.min = 0; property->range.max = 0xff; property->stepping = 1.0; return STATUS_SUCCESS; } break; default: break; } return status; } unicap_status_t tiseuvccam_override_property( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( !ctrl ) { if( !strcmp( property->identifier, "frame rate" ) ) { struct v4l2_control ctrl; memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EUVC_REGISTER; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { // XU control not added to the driver return STATUS_NO_MATCH; } handle->frame_rate = 30.0; property->type = UNICAP_PROPERTY_TYPE_VALUE_LIST; property->value = 30.0; property->value_list.values = frame_rates; property->value_list.value_count = sizeof( frame_rates ) / sizeof( double ); return STATUS_SUCCESS; } else { return STATUS_NO_MATCH; } } switch( ctrl->id ) { #ifdef V4L2_CID_PRIVACY_CONTROL case V4L2_CID_PRIVACY_CONTROL: if( property ) { strcpy( property->identifier, N_("trigger") ); strcpy( property->category, N_("device" ) ); strcpy( property->unit, "" ); property->flags_mask = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF; property->flags = UNICAP_FLAGS_MANUAL; property->type = UNICAP_PROPERTY_TYPE_FLAGS; } status = STATUS_SUCCESS; break; #endif case V4L2_CID_EXPOSURE_AUTO: status = STATUS_SKIP_CTRL; break; case V4L2_CID_EXPOSURE_ABSOLUTE: if( property ) { strcpy( property->identifier, N_("shutter") ); strcpy( property->category, N_("exposure") ); strcpy( property->unit, "s" ); if( TRUE /* handle->pid == 0x8203 */ ) { property->flags_mask = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO; property->flags = UNICAP_FLAGS_AUTO; } else { property->flags_mask = UNICAP_FLAGS_MANUAL; property->flags = UNICAP_FLAGS_MANUAL; } property->type = UNICAP_PROPERTY_TYPE_RANGE; property->range.min = (double)ctrl->minimum / 10000.0; property->range.max = (double)ctrl->maximum / 10000.0; property->value = (double)ctrl->default_value / 10000.0; } status = STATUS_SUCCESS; break; case V4L2_CID_GAIN: if( property ) { strcpy( property->identifier, N_("gain") ); strcpy( property->category, N_("exposure" ) ); if( TRUE /* handle->pid != 0x8203 */ ) { property->flags_mask = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO; property->flags = UNICAP_FLAGS_AUTO; } else { property->flags_mask = UNICAP_FLAGS_MANUAL; property->flags = UNICAP_FLAGS_MANUAL; } property->type = UNICAP_PROPERTY_TYPE_RANGE; property->range.min = (double)ctrl->minimum; property->range.max = (double)ctrl->maximum; property->stepping = 1.0; property->value = (double)ctrl->default_value; } status = STATUS_SUCCESS; break; /* case V4L2_CID_WHITE */ default: break; } return status; } unicap_status_t tiseuvccam_set_property( v4l2_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( !strcmp( property->identifier, "trigger" ) ) { #ifdef V4L2_CID_PRIVACY_CONTROL struct v4l2_control ctrl; memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_PRIVACY_CONTROL; ctrl.value = ( ( property->flags & UNICAP_FLAGS_ON_OFF ) == UNICAP_FLAGS_ON_OFF ) ? 1 : 0; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } else { status = STATUS_SUCCESS; } #else return STATUS_FAILURE; #endif } else if( !strcmp( property->identifier, "shutter" ) ) { struct v4l2_control ctrl; int shift = 1; if( handle->pid == 0x8201 ) { shift = 2; } memset( &ctrl, 0x0, sizeof( ctrl ) ); if( (handle->pid != 0x8203 ) && ( handle->pid != 0x8204 ) ) { ctrl.id = V4L2_CID_EXPOSURE_AUTO; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed\n" ); return STATUS_FAILURE; } ctrl.value &= ~(1<flags & UNICAP_FLAGS_AUTO ) { ctrl.value |= 1<fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } } if( property->flags & UNICAP_FLAGS_MANUAL ) { memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE; ctrl.value = property->value * 10000; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } status = STATUS_SUCCESS; } } else if( !strcmp( property->identifier, "gain" ) ) { struct v4l2_control ctrl; int shift = 1; if( handle->pid == 0x8201 ) { shift = 2; } memset( &ctrl, 0x0, sizeof( ctrl ) ); if( (handle->pid != 0x8203 ) && ( handle->pid != 0x8204 ) ) { ctrl.id = V4L2_CID_EXPOSURE_AUTO; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed\n" ); return STATUS_FAILURE; } ctrl.value &= ~(2<flags & UNICAP_FLAGS_AUTO ) { ctrl.value |= 2<fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } } if( property->flags & UNICAP_FLAGS_MANUAL ) { memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_GAIN; ctrl.value = property->value; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } } status = STATUS_SUCCESS; } else if( !strcmp( property->identifier, "frame rate" ) ) { struct v4l2_control ctrl; double d = 9999999; int sel = 0, i; memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EUVC_REGISTER; for( i = 0; i < ( sizeof( frame_rates ) / sizeof( double ) ); i ++ ) { if( abs( property->value - frame_rates[i] < d ) ) { d = abs( property->value - frame_rates[i] < d ); sel = i; } } ctrl.value = ( (unsigned int )frame_rate_register_values[sel] << 16) | (0x01 <<8) | 0x3a; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "failed to set frame rate control\n" ); status = STATUS_FAILURE; } handle->frame_rate = frame_rates[sel]; status = STATUS_SUCCESS; } else if( !strcmp( property->identifier, "sharpness register" ) ) { struct v4l2_control ctrl; int val; val = property->value; val &= 0xff; memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EUVC_REGISTER; ctrl.value = ( val << 16) | (0x01 <<8) | 0x23; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "sharpness register\n" ); status = STATUS_FAILURE; } ctrl.value = ( val << 16) | (0x01 <<8) | 0x24; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "sharpness register\n" ); status = STATUS_FAILURE; } /* handle->sharpness_register = val; */ status = STATUS_SUCCESS; } return status; } unicap_status_t tiseuvccam_get_property( v4l2_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( !strcmp( property->identifier, "trigger" ) ) { #ifdef V4L2_CID_PRIVACY_CONTROL struct v4l2_control ctrl; memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_PRIVACY_CONTROL; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed\n" ); return STATUS_FAILURE; } else { status = STATUS_SUCCESS; } if( ctrl.value ) { property->flags = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_ON_OFF; } else { property->flags = UNICAP_FLAGS_MANUAL; } #else return STATUS_FAILURE; #endif } else if( !strcmp( property->identifier, "shutter" ) ) { struct v4l2_control ctrl; int shift = 1; if( handle->pid == 0x8201 ) { shift = 2; } memset( &ctrl, 0x0, sizeof( ctrl ) ); property->flags = UNICAP_FLAGS_MANUAL; if( (handle->pid != 0x8203 ) && ( handle->pid != 0x8204 ) ) { ctrl.id = V4L2_CID_EXPOSURE_AUTO; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL ( V4L2_CID_EXPOSURE_AUTO ) failed\n" ); return STATUS_FAILURE; } else { status = STATUS_SUCCESS; } if( !(ctrl.value & (1<flags = UNICAP_FLAGS_AUTO; } else { property->flags = UNICAP_FLAGS_MANUAL; } } memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed!\n" ); return STATUS_FAILURE; } else { property->value = ctrl.value / 10000.0; status = STATUS_SUCCESS; } } else if( !strcmp( property->identifier, "gain" ) ) { struct v4l2_control ctrl; int shift = 1; if( handle->pid == 0x8201 ) { shift = 2; } memset( &ctrl, 0x0, sizeof( ctrl ) ); property->flags = UNICAP_FLAGS_MANUAL; if( (handle->pid != 0x8203 ) && ( handle->pid != 0x8204 ) ) { ctrl.id = V4L2_CID_EXPOSURE_AUTO; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL ( V4L2_CID_EXPOSURE_AUTO ) failed\n" ); return STATUS_FAILURE; } else { status = STATUS_SUCCESS; } if( !(ctrl.value & (2<flags = UNICAP_FLAGS_AUTO; } else { property->flags = UNICAP_FLAGS_MANUAL; } } memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_GAIN; if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed!\n" ); return STATUS_FAILURE; } else { property->value = ctrl.value; status = STATUS_SUCCESS; } } else if( !strcmp( property->identifier, "frame rate" ) ) { property->value = handle->frame_rate; status = STATUS_SUCCESS; } else if( !strcmp( property->identifier, "Register" ) ) { struct v4l2_control ctrl; int val; val = property->value; val &= 0xff; memset( &ctrl, 0x0, sizeof( ctrl ) ); ctrl.id = V4L2_CID_EUVC_REGISTER; ctrl.value = val; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "register\n" ); status = STATUS_FAILURE; } ctrl.value = val; if( IOCTL( handle->fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "register\n" ); status = STATUS_FAILURE; } if( IOCTL( handle->fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "register\n" ); status = STATUS_FAILURE; } property->value = ctrl.value; status = STATUS_SUCCESS; } else if( !strcmp( property->identifier, "sharpness register" ) ) { /* property->value = handle->sharpness_register; */ property->flags = UNICAP_FLAGS_MANUAL; status = STATUS_SUCCESS; } return status; } unicap_status_t tiseuvccam_fmt_get( struct v4l2_fmtdesc *v4l2fmt, struct v4l2_cropcap *cropcap, char **identifier, unsigned int *fourcc, int *bpp ) { unicap_status_t status = STATUS_NO_MATCH; TRACE( "fmt_get desc='%s', defrect.width=%d\n", v4l2fmt->description, cropcap->defrect.width ); if( ( (float)cropcap->defrect.width / (float)cropcap->defrect.height ) < 1.0 ) { if( ( v4l2fmt->pixelformat == FOURCC( 'Y', 'U', 'Y', 'V' ) ) /* && */ /* ( ( cropcap->defrect.width == 372 ) || ( cropcap->defrect.width == 320 ) || ( cropcap->defrect.width == 1024 ) */ /* || ( cropcap->defrect.width == 512 ) ) */ ) { if( identifier ) { *identifier = "Y800"; } if( fourcc ) { *fourcc = FOURCC( 'Y', '8', '0', '0' ); } if( bpp ) { *bpp = 8; } cropcap->defrect.width *= 2; cropcap->bounds.width *= 2; status = STATUS_SUCCESS; } else if( ( v4l2fmt->pixelformat == FOURCC( 'U', 'Y', 'V', 'Y' ) ) /* && */ /* ( ( cropcap->defrect.width == 372 ) || ( cropcap->defrect.width == 320 ) || ( cropcap->defrect.width == 1024 ) */ /* || ( cropcap->defrect.width == 512 ) ) */ ) { TRACE( "skip format: %s\n", v4l2fmt->description ); status = STATUS_SKIP_CTRL; } } TRACE( "fmt get: id = %s width= %d\n", identifier ? *identifier : "", cropcap->defrect.width ); return status; } #ifdef VIDIOC_ENUM_FRAMESIZES unicap_status_t tiseuvccam_override_framesize( v4l2_handle_t handle, struct v4l2_frmsizeenum *frms ) { unicap_status_t status = STATUS_NO_MATCH; /* if( ( frms->discrete.height == 480 && ( ( frms->discrete.width == 372 ) || ( frms->discrete.width == 320 ) ) ) || */ /* ( frms->discrete.height == 1532 && ( ( frms->discrete.width == 1024 ) ) ) || */ /* ( frms->discrete.height == 768 && ( frms->discrete.width == 512 ) ) */ /* ) */ /* { */ if( handle->pid != 0x8201 ) { frms->discrete.width *= 2; status = STATUS_SUCCESS; } /* } */ return status; } #endif unicap_status_t tiseuvccam_tov4l2format( v4l2_handle_t handle, unicap_format_t *format ) { unicap_status_t status = STATUS_NO_MATCH; usleep(100000); if( format->fourcc == FOURCC( 'Y', '8', '0', '0' ) ) { format->fourcc = FOURCC( 'Y', 'U', 'Y', 'V' ); format->size.width /= 2; format->bpp = 16; status = STATUS_SUCCESS; } return status; } libunicap/cpi/v4l2cpi/tisuvccam.c0000644000175000017500000006354313164711411017470 0ustar zmoelnigzmoelnig/* ** tisuvccam.c ** ** Made by (Arne Caspari) ** Login ** ** Started on Tue Jan 8 07:22:47 2008 Arne Caspari */ #include "config.h" #include "tisuvccam.h" #include #include #include #include #include "uvcvideo.h" #if V4L2_DEBUG #define DEBUG #endif #include "debug.h" #define N_(x) x #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a) #define UVC_GUID_TISUVC_XU {0x0a, 0xba, 0x49, 0xde, 0x5c, 0x0b, 0x49, 0xd5, \ 0x8f, 0x71, 0x0b, 0xe4, 0x0f, 0x94, 0xa6, 0x7a} #define V4L2_CID_AUTO_GAIN 0x00980920 #define V4L2_CID_AUTO_SHUTTER 0x00980921 #define V4L2_CID_WHITE_BALANCE_ONE_PUSH 0x00980922 #define V4L2_CID_AUTO_SHUTTER_MAX 0x00980923 #define V4L2_CID_AUTO_SHUTTER_MAX_AUTO 0x00980924 #define V4L2_CID_TRIGGER 0x00980925 #if USE_LIBV4L #define OPEN v4l2_open #define CLOSE v4l2_close #define IOCTL v4l2_ioctl #define MMAP v4l2_mmap #define MUNMAP v4l2_munmap #else #define OPEN open #define CLOSE close #define IOCTL ioctl #define MMAP mmap #define MUNMAP munmap #endif typedef enum { XU_AUTO_SHUTTER = 0x1, XU_AUTO_GAIN = 0x2, XU_ONE_PUSH_WB = 0x3, XU_AUTO_EXPOSURE_REF = 0x4, XU_TRIGGER = 0x5, XU_STROBE_MODE = 0x6, XU_STROBE_PARAMS = 0x7, XU_GPIO = 0x8, XU_AUTO_SHUTTER_MAX = 0x9, XU_AUTO_SHUTTER_MAX_AUTO = 0xa, XU_AVG_FRAMES = 0xe, } TISUVCCtrlIdx; typedef enum { CTRL_TYPE_BITMAP = 0, CTRL_TYPE_RANGE, } TISUVCCtrlType; struct ctrlrange { int min; int max; }; struct ppty_info { char identifier[128]; unicap_status_t (*set_func)(int fd, unicap_property_t *property); unicap_status_t (*get_func)(int fd, unicap_property_t *property); }; struct ctrlinfo { struct uvc_xu_control_info xu_ctrl_info; TISUVCCtrlType type; union { unsigned int bitmap_mask; struct ctrlrange range; }; int def; int has_property; unicap_property_t property; }; struct uvc_format { __u8 type; __u8 index; __u8 bpp; __u8 colorspace; __u32 fcc; __u32 flags; char name[32]; unsigned int nframes; struct uvc_frame *frame; }; static unicap_status_t tisuvccam_set_shutter( int fd, unicap_property_t *property ); static unicap_status_t tisuvccam_get_shutter( int fd, unicap_property_t *property ); static unicap_status_t tisuvccam_set_gain( int fd, unicap_property_t *property ); static unicap_status_t tisuvccam_get_gain( int fd, unicap_property_t *property ); static unicap_status_t tisuvccam_set_wb_auto( int fd, unicap_property_t *property ); static unicap_status_t tisuvccam_get_wb_auto( int fd, unicap_property_t *property ); #define TRIGGER_FREE_RUNNING "free running" #define TRIGGER_FALLING_EDGE "trigger on falling edge" #define TRIGGER_RISING_EDGE "trigger on rising edge" static char* trigger_menu[] = { N_(TRIGGER_FREE_RUNNING), N_(TRIGGER_FALLING_EDGE), N_(TRIGGER_RISING_EDGE) }; static struct ctrlinfo TISUVCCtrlInfo[] = { { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 0, selector: XU_AUTO_SHUTTER, size: 1, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_BITMAP, {bitmap_mask: 0x1}, def: 0x1, has_property: 0, property:{ identifier: N_("auto shutter"), category: N_("exposure"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_AUTO, flags_mask: UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0 } }, { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 1, selector: XU_AUTO_GAIN, size: 1, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_BITMAP, {bitmap_mask: 0x1}, def: 0x1, has_property: 0, property:{ identifier: N_("auto gain"), category: N_("exposure"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_AUTO, flags_mask: UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0 } }, { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 2, selector: XU_ONE_PUSH_WB, size: 1, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_BITMAP, {bitmap_mask: 0x1}, def: 0x1, has_property: 0, property:{ identifier: N_("one push wb"), category: N_("color"), unit: "", relations: NULL, relations_count: 0, {value: 0}, {range: { min: 0, max: 0 } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_FLAGS, flags: UNICAP_FLAGS_ONE_PUSH, flags_mask: UNICAP_FLAGS_ONE_PUSH, property_data: NULL, property_data_size: 0 } }, { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 3, selector: XU_AUTO_EXPOSURE_REF, size: 4, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_RANGE, {range: { 0, 255 }}, def: 128, has_property: 1, property:{ identifier: N_("auto exposure reference"), category: N_("exposure"), unit: "", relations: NULL, relations_count: 0, {value: 128}, {range: { min: 0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 } }, { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 4, selector: XU_AUTO_SHUTTER_MAX, size: 4, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_RANGE, {range: { 1, 5000 }}, def: 333, has_property: 1, property:{ identifier: N_("auto shutter maximum"), category: N_("exposure"), unit: N_("s"), relations: NULL, relations_count: 0, {value: 0.03333}, {range: { min: 0.0001, max: 0.5 } }, stepping: 0.0001, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, flags_mask: UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO, property_data: NULL, property_data_size: 0 } }, { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 5, selector: XU_TRIGGER, size: 1, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_BITMAP, {bitmap_mask: 0x3}, def: 0x0, has_property: 1, property:{ identifier: N_("trigger"), category: N_("device"), unit: "", relations: NULL, relations_count: 0, {menu_item: TRIGGER_FREE_RUNNING}, {menu: { menu_items: trigger_menu, menu_item_count: sizeof( trigger_menu ) / sizeof( char * ) } }, stepping: 0.0, type: UNICAP_PROPERTY_TYPE_MENU, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 } }, { xu_ctrl_info: { UVC_GUID_TISUVC_XU, index: 6, selector: XU_AVG_FRAMES, size: 4, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR }, CTRL_TYPE_RANGE, {range: { 1, 255 }}, def: 1, has_property: 1, property:{ identifier: N_("auto exposure average frames"), category: N_("exposure"), unit: "", relations: NULL, relations_count: 0, {value: 1.0}, {range: { min: 1.0, max: 255 } }, stepping: 1.0, type: UNICAP_PROPERTY_TYPE_RANGE, flags: UNICAP_FLAGS_MANUAL, flags_mask: UNICAP_FLAGS_MANUAL, property_data: NULL, property_data_size: 0 } }, }; static struct ppty_info TISUVCPropertyOverrides[] = { { "shutter", tisuvccam_set_shutter, tisuvccam_get_shutter, }, { "gain", tisuvccam_set_gain, tisuvccam_get_gain, }, { "white balance mode", tisuvccam_set_wb_auto, tisuvccam_get_wb_auto } }; static struct uvc_format TISUVCFormats[] = { { type: V4L2_BUF_TYPE_VIDEO_CAPTURE, bpp: 8, colorspace: 0, fcc: FOURCC( 'Y', '8', '0', '0' ), flags: 0, name: "30303859-0000-0010-8000-00aa003", } }; static void tisuvccam_add_controls( int fd ) { int i; int n = sizeof( TISUVCCtrlInfo ) / sizeof( struct ctrlinfo ); struct uvc_xu_control_info extinfos[] = { { UVC_GUID_TISUVC_XU, index: 7, selector: XU_AUTO_SHUTTER_MAX_AUTO, size: 1, flags: UVC_CONTROL_GET_CUR | UVC_CONTROL_SET_CUR } }; for( i = 0; i < n; i++ ) { if( IOCTL( fd, UVCIOC_CTRL_ADD, &TISUVCCtrlInfo[i].xu_ctrl_info ) < 0 ) { TRACE( "Failed to add info for control: %d\n", i ); } } n = sizeof( extinfos ) / sizeof( struct uvc_xu_control_info ); for( i = 0; i < n; i++ ) { if( IOCTL( fd, UVCIOC_CTRL_ADD, &extinfos[i] ) < 0 ) { TRACE( "Failed to add info for control: %d\n", i ); } } } static void tisuvccam_add_formats( int fd ) { /* int i; */ /* int n = sizeof( TISUVCFormats ) / sizeof( struct uvc_format ); */ /* for( i = 0; i < n; i++ ) */ /* { */ /* if( ioctl( fd, UVCIOC_FMT_SET, &TISUVCFormats[i] ) < 0 ) */ /* { */ /* TRACE( "Failed to set format info for %d\n", i ); */ /* } */ /* } */ } int tisuvccam_probe( v4l2_handle_t handle, const char *path ) { __u8 data; int ret = 0; struct uvc_xu_control xuctrl = { unit: 6, selector: XU_AUTO_SHUTTER, size: 1, data: &data, }; tisuvccam_add_controls( handle->fd ); if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { TRACE( "tisuvccam_probe: not a TIS UVC device\n" ); } else { TRACE( "tisuvccam_probe: found TIS UVC device\n" ); ret = 1; } return ret; } int tisuvccam_count_ext_property( v4l2_handle_t handle ) { int i; int cnt = 0; int n = sizeof( TISUVCCtrlInfo ) / sizeof( struct ctrlinfo ); for( i = 0; i < n; ++i ) { __u32 data; if( TISUVCCtrlInfo[i].has_property ) { struct uvc_xu_control xuctrl; xuctrl.unit = 6; xuctrl.selector = TISUVCCtrlInfo[i].xu_ctrl_info.selector; xuctrl.size = TISUVCCtrlInfo[i].xu_ctrl_info.size; xuctrl.data = (__u8*)&data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) >= 0 ) { TRACE( "tisuvccam_count: found property - selector = %d\n", TISUVCCtrlInfo[i].xu_ctrl_info.selector ); cnt++; } } } return cnt; } unicap_status_t tisuvccam_override_property( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ) { unicap_status_t status = STATUS_NO_MATCH; if( !ctrl ) { return STATUS_NO_MATCH; } switch( ctrl->id ) { case V4L2_CID_EXPOSURE_ABSOLUTE: { if( property ) { strcpy( property->identifier, N_("shutter") ); strcpy( property->category, N_("exposure") ); strcpy( property->unit, N_("s") ); property->flags_mask = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO | UNICAP_FLAGS_READ_OUT; property->flags = UNICAP_FLAGS_AUTO; property->type = UNICAP_PROPERTY_TYPE_RANGE; property->range.min = (double)ctrl->minimum / 10000.0; property->range.max = (double)ctrl->maximum / 10000.0; property->value = (double)ctrl->default_value / 10000.0; } status = STATUS_SUCCESS; } break; case V4L2_CID_GAIN: { if( property ) { strcpy( property->identifier, N_("gain") ); strcpy( property->category, N_("exposure") ); strcpy( property->unit, "" ); property->flags_mask = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO | UNICAP_FLAGS_READ_OUT; property->flags = UNICAP_FLAGS_AUTO; property->type = UNICAP_PROPERTY_TYPE_RANGE; property->range.min = (double)ctrl->minimum; property->range.max = (double)ctrl->maximum; property->value = (double)ctrl->default_value; } status = STATUS_SUCCESS; } break; case V4L2_CID_AUTO_WHITE_BALANCE: { if( property ) { unicap_void_property( property ); strcpy( property->identifier, N_("white balance mode") ); strcpy( property->category, N_("color") ); property->flags_mask = UNICAP_FLAGS_MANUAL | UNICAP_FLAGS_AUTO | UNICAP_FLAGS_READ_OUT; property->flags = UNICAP_FLAGS_AUTO; property->type = UNICAP_PROPERTY_TYPE_FLAGS; } status = STATUS_SUCCESS; } break; case V4L2_CID_EXPOSURE_AUTO: case V4L2_CID_AUTO_GAIN: case V4L2_CID_AUTO_SHUTTER: case V4L2_CID_WHITE_BALANCE_ONE_PUSH: case V4L2_CID_AUTO_SHUTTER_MAX: case V4L2_CID_AUTO_SHUTTER_MAX_AUTO: case V4L2_CID_TRIGGER: { TRACE( "Skip control %x: '%s'\n", ctrl->id, ctrl->name ); status = STATUS_SKIP_CTRL; } break; default: break; } if( SUCCESS( status ) ) { TRACE( "Using override for property '%s'\n", property->identifier ); } return status; } unicap_status_t tisuvccam_enumerate_properties( v4l2_handle_t handle, int index, unicap_property_t *property ) { int i; int n; int tmp_index = -1; unicap_status_t status = STATUS_NO_MATCH; n = sizeof( TISUVCCtrlInfo ) / sizeof( struct ctrlinfo ); for( i = 0; ( i < n ) && ( tmp_index < index ); ++i ) { __u32 data; struct uvc_xu_control xuctrl; xuctrl.unit = 6; xuctrl.selector = TISUVCCtrlInfo[i].xu_ctrl_info.selector; xuctrl.size = TISUVCCtrlInfo[i].xu_ctrl_info.size; xuctrl.data = (__u8*)&data; if( TISUVCCtrlInfo[i].has_property ) { if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) >= 0 ) { tmp_index++; if( tmp_index == index ) { TRACE( "UVCIOC_CTRL_GET: Found control %d\n", xuctrl.selector ); unicap_copy_property( property, &TISUVCCtrlInfo[i].property ); status = STATUS_SUCCESS; break; } } else { TRACE( "UVCIOC_CTRL_GET failed for selector: %d\n", xuctrl.selector ); } } } return status; } unicap_status_t tisuvccam_set_property( v4l2_handle_t handle, unicap_property_t *property ) { int n; int i; int index = -1; unicap_status_t status = STATUS_FAILURE; struct uvc_xu_control xuctrl; __u32 data; n = sizeof( TISUVCPropertyOverrides ) / sizeof( struct ppty_info ); for( i = 0; i < n; ++i ) { if( !strcmp( property->identifier, TISUVCPropertyOverrides[i].identifier ) ) { return TISUVCPropertyOverrides[i].set_func( handle->fd, property ); } } n = sizeof( TISUVCCtrlInfo) / sizeof( struct ctrlinfo ); for( i = 0; i < n; ++i ) { if( !strcmp( property->identifier, TISUVCCtrlInfo[i].property.identifier ) ) { index = i; break; } } if( index < 0 ) { return STATUS_NO_MATCH; } xuctrl.unit = 6; xuctrl.selector = TISUVCCtrlInfo[index].xu_ctrl_info.selector; xuctrl.size = TISUVCCtrlInfo[index].xu_ctrl_info.size; xuctrl.data = (__u8*)&data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { return STATUS_NO_MATCH; } switch( TISUVCCtrlInfo[index].xu_ctrl_info.selector ) { case XU_AUTO_SHUTTER_MAX: { struct uvc_xu_control autoctrl; __u8 u8data; /* u8data = ( property->flags & UNICAP_FLAGS_AUTO ) ? 1 : 0; */ /* autoctrl.unit = 6; */ /* autoctrl.selector = XU_AUTO_SHUTTER_MAX_AUTO; */ /* autoctrl.size = 1; */ /* autoctrl.data = &u8data; */ /* if( IOCTL( handle->fd, UVCIOC_CTRL_SET, &autoctrl ) < 0 ) */ /* { */ /* TRACE( "failed to set XU_AUTO_SHUTTER_MAX_AUTO!\n" ); */ /* status = STATUS_FAILURE; */ /* break; */ /* } */ /* data = property->value * 10000; */ data = property->value; if( IOCTL( handle->fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } status = STATUS_SUCCESS; } break; case XU_AUTO_SHUTTER: case XU_AUTO_GAIN: { __u8 u8data; u8data = ( property->flags & UNICAP_FLAGS_AUTO ) ? 1 : 0; xuctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } status = STATUS_SUCCESS; } break; case XU_ONE_PUSH_WB: { __u8 u8data; u8data = ( property->flags & UNICAP_FLAGS_ONE_PUSH ) ? 1 : 0; xuctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } status = STATUS_SUCCESS; } break; case XU_AUTO_EXPOSURE_REF: case XU_AVG_FRAMES: { data = property->value; if( IOCTL( handle->fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } status = STATUS_SUCCESS; } break; case XU_TRIGGER: { __u8 u8data; if( !strcmp( property->menu_item, TRIGGER_FREE_RUNNING ) ) { u8data = 0; } else if( !strcmp( property->menu_item, TRIGGER_FALLING_EDGE ) ) { u8data = 0x1; } else if( !strcmp( property->menu_item, TRIGGER_RISING_EDGE ) ) { u8data = 0x3; } xuctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } status = STATUS_SUCCESS; } break; default: { TRACE( "Unknown/Unhandled unit!\n"); status = STATUS_NO_MATCH; } break; } if( !SUCCESS( status ) ) { TRACE( "Failed to set property: %s\n", property->identifier ); } return status; } unicap_status_t tisuvccam_get_property( v4l2_handle_t handle, unicap_property_t *property ) { int n; int i; int index = -1; unicap_status_t status = STATUS_FAILURE; struct uvc_xu_control xuctrl; __u32 data; n = sizeof( TISUVCPropertyOverrides ) / sizeof( struct ppty_info ); for( i = 0; i < n; ++i ) { if( !strcmp( property->identifier, TISUVCPropertyOverrides[i].identifier ) ) { return TISUVCPropertyOverrides[i].get_func( handle->fd, property ); } } n = sizeof( TISUVCCtrlInfo ) / sizeof( struct ctrlinfo ); for( i = 0; i < n; ++i ) { if( !strcmp( property->identifier, TISUVCCtrlInfo[i].property.identifier ) ) { index = i; break; } } if( index < 0 ) { return STATUS_NO_MATCH; } xuctrl.unit = 6; xuctrl.selector = TISUVCCtrlInfo[index].xu_ctrl_info.selector; xuctrl.size = TISUVCCtrlInfo[index].xu_ctrl_info.size; xuctrl.data = (__u8*)&data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { return STATUS_NO_MATCH; } unicap_copy_property( property, &TISUVCCtrlInfo[index].property ); switch( TISUVCCtrlInfo[index].xu_ctrl_info.selector ) { case XU_AUTO_SHUTTER_MAX: { struct uvc_xu_control autoctrl; __u8 u8data; autoctrl.unit = 6; autoctrl.selector = XU_AUTO_SHUTTER_MAX_AUTO; autoctrl.size = 1; autoctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &autoctrl ) < 0 ) { TRACE( "failed to get XU_AUTO_SHUTTER_MAX_AUTO!\n" ); status = STATUS_FAILURE; break; } property->flags = u8data ? UNICAP_FLAGS_AUTO : UNICAP_FLAGS_MANUAL; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } property->value = (double)data / 10000.0; status = STATUS_SUCCESS; } break; case XU_AUTO_SHUTTER: case XU_AUTO_GAIN: { __u8 u8data; xuctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } property->flags = u8data ? UNICAP_FLAGS_AUTO : UNICAP_FLAGS_MANUAL; status = STATUS_SUCCESS; } break; case XU_ONE_PUSH_WB: { __u8 u8data; xuctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } property->flags = u8data ? UNICAP_FLAGS_ONE_PUSH : UNICAP_FLAGS_MANUAL; status = STATUS_SUCCESS; } break; case XU_AUTO_EXPOSURE_REF: case XU_AVG_FRAMES: { if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } property->value = data; status = STATUS_SUCCESS; } break; case XU_TRIGGER: { __u8 u8data; xuctrl.data = &u8data; if( IOCTL( handle->fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { status = STATUS_FAILURE; break; } status = STATUS_SUCCESS; switch( data & 0x3 ) { case 0x0: case 0x2: strcpy( property->menu_item, TRIGGER_FREE_RUNNING ); break; case 0x1: strcpy( property->menu_item, TRIGGER_FALLING_EDGE ); break; case 0x3: strcpy( property->menu_item, TRIGGER_RISING_EDGE ); break; default: break; } } break; default: { TRACE( "Unknown/Unhandled unit!\n"); status = STATUS_NO_MATCH; } break; } if( !SUCCESS( status ) ) { TRACE( "Failed to get property: %s\n", property->identifier ); } return status; } unicap_status_t tisuvccam_fmt_get( struct v4l2_fmtdesc *v4l2fmt, struct v4l2_cropcap *cropcap, char **identifier, unsigned int *fourcc, int *bpp ) { unicap_status_t status = STATUS_NO_MATCH; if( !strcmp( (char*)v4l2fmt->description, "30303859-0000-0010-8000-00aa003" ) ) { if( identifier ) { *identifier = "Y800"; } /* if( fourcc ) */ /* { */ /* *fourcc = FOURCC( 'Y', '8', '0', '0' ); */ /* } */ if( bpp ) { *bpp = 8; } status = STATUS_SUCCESS; } else if( !strcmp( (char*)v4l2fmt->description, "20385942-0000-0010-8000-00aa003" ) ) { // BY8 if( identifier ) { *identifier = "8-Bit Bayer RAW"; } /* if( fourcc ) */ /* { */ /* *fourcc = FOURCC( 'B', 'Y', '8', ' ' ); */ /* } */ if( bpp ) { *bpp = 8; } status = STATUS_SUCCESS; } return status; } static unicap_status_t tisuvccam_set_shutter( int fd, unicap_property_t *property ) { struct uvc_xu_control xuctrl; __u8 u8data; xuctrl.unit = 6; xuctrl.selector = XU_AUTO_SHUTTER; xuctrl.size = 1; u8data = ( property->flags & UNICAP_FLAGS_AUTO ) ? 1 : 0; xuctrl.data = &u8data; if( IOCTL( fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { TRACE( "UVCIOC_CTRL_SET failed!\n" ); return STATUS_FAILURE; } if( property->flags & UNICAP_FLAGS_MANUAL ) { struct v4l2_control ctrl; ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE; ctrl.value = property->value * 10000; if( IOCTL( fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } } return STATUS_SUCCESS; } static unicap_status_t tisuvccam_get_shutter( int fd, unicap_property_t *property ) { struct uvc_xu_control xuctrl; struct v4l2_control ctrl; __u8 u8data; xuctrl.unit = 6; xuctrl.selector = XU_AUTO_SHUTTER; xuctrl.size = 1; xuctrl.data = &u8data; if( IOCTL( fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { TRACE( "UVCIOC_CTRL_GET failed!\n" ); return STATUS_FAILURE; } property->flags = u8data ? UNICAP_FLAGS_AUTO : UNICAP_FLAGS_MANUAL; ctrl.id = V4L2_CID_EXPOSURE_ABSOLUTE; if( IOCTL( fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed!\n" ); return STATUS_FAILURE; } property->value = (double)ctrl.value / 10000.0; return STATUS_SUCCESS; } static unicap_status_t tisuvccam_set_gain( int fd, unicap_property_t *property ) { struct uvc_xu_control xuctrl; __u8 u8data; xuctrl.unit = 6; xuctrl.selector = XU_AUTO_GAIN; xuctrl.size = 1; u8data = ( property->flags & UNICAP_FLAGS_AUTO ) ? 1 : 0; xuctrl.data = &u8data; if( IOCTL( fd, UVCIOC_CTRL_SET, &xuctrl ) < 0 ) { TRACE( "UVCIOC_CTRL_SET failed!\n" ); return STATUS_FAILURE; } if( property->flags & UNICAP_FLAGS_MANUAL ) { struct v4l2_control ctrl; ctrl.id = V4L2_CID_GAIN; ctrl.value = property->value; if( IOCTL( fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed\n" ); return STATUS_FAILURE; } } return STATUS_SUCCESS; } static unicap_status_t tisuvccam_get_gain( int fd, unicap_property_t *property ) { struct uvc_xu_control xuctrl; struct v4l2_control ctrl; __u8 u8data; xuctrl.unit = 6; xuctrl.selector = XU_AUTO_GAIN; xuctrl.size = 1; xuctrl.data = &u8data; if( IOCTL( fd, UVCIOC_CTRL_GET, &xuctrl ) < 0 ) { TRACE( "UVCIOC_CTRL_GET failed!\n" ); return STATUS_FAILURE; } property->flags = u8data ? UNICAP_FLAGS_AUTO : UNICAP_FLAGS_MANUAL; ctrl.id = V4L2_CID_GAIN; if( IOCTL( fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed!\n" ); return STATUS_FAILURE; } property->value = (double)ctrl.value; return STATUS_SUCCESS; } static unicap_status_t tisuvccam_set_wb_auto( int fd, unicap_property_t *property ) { struct v4l2_control ctrl; unicap_status_t status = STATUS_SUCCESS; ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE; ctrl.value = ( property->flags & UNICAP_FLAGS_AUTO ) ? 1 : 0; if( IOCTL( fd, VIDIOC_S_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_S_CTRL failed!\n" ); status = STATUS_FAILURE; } return status; } static unicap_status_t tisuvccam_get_wb_auto( int fd, unicap_property_t *property ) { struct v4l2_control ctrl; unicap_status_t status = STATUS_SUCCESS; ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE; if( IOCTL( fd, VIDIOC_G_CTRL, &ctrl ) < 0 ) { TRACE( "VIDIOC_G_CTRL failed!\n" ); status = STATUS_FAILURE; } if( ctrl.value ){ property->flags = UNICAP_FLAGS_AUTO; }else{ property->flags = UNICAP_FLAGS_MANUAL; } return status; } libunicap/cpi/v4l2cpi/tiseuvccam.h0000644000175000017500000000221013164711411017622 0ustar zmoelnigzmoelnig/* ** tiseuvccam.h ** ** Made by Arne Caspari */ #ifndef TISEUVCCAM_H_ # define TISEUVCCAM_H_ #include #include #include #include "v4l2.h" int tiseuvccam_probe( v4l2_handle_t handle, const char *path ); int tiseuvccam_count_ext_property( v4l2_handle_t handle ); unicap_status_t tiseuvccam_enumerate_properties( v4l2_handle_t handle, int index, unicap_property_t *property ); unicap_status_t tiseuvccam_override_property( v4l2_handle_t handle, struct v4l2_queryctrl *ctrl, unicap_property_t *property ); unicap_status_t tiseuvccam_set_property( v4l2_handle_t handle, unicap_property_t *property ); unicap_status_t tiseuvccam_get_property( v4l2_handle_t handle, unicap_property_t *property ); unicap_status_t tiseuvccam_fmt_get( struct v4l2_fmtdesc *v4l2fmt, struct v4l2_cropcap *cropcap, char **identifier, unsigned int *fourcc, int *bpp ); unicap_status_t tiseuvccam_tov4l2format( v4l2_handle_t handle, unicap_format_t *format ); #ifdef VIDIOC_ENUM_FRAMESIZES unicap_status_t tiseuvccam_override_framesize( v4l2_handle_t handle, struct v4l2_frmsizeenum *frms ); #endif #endif /* !TISEUVCCAM_H_ */ libunicap/cpi/v4l/0000755000175000017500000000000013164711411014535 5ustar zmoelnigzmoelniglibunicap/cpi/v4l/Makefile.am0000644000175000017500000000071613164711411016575 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in INCLUDES = -I../include -I../../include -I../../common if ENABLE_STATIC_CPI noinst_LTLIBRARIES = libv4l.la libv4l_la_LIBADD = @PTHREAD_LIBS@ -L../../common -lucutils else libcpi_LTLIBRARIES = libv4l.la libv4l_la_LIBADD = @PTHREAD_LIBS@ -L../../src/.libs/ -lunicap -L../../common -lucutils endif libcpidir = $(libdir)/unicap$(pkg_version)/cpi libv4l_la_LDFLAGS = -module -avoid-version libv4l_la_SOURCES = \ v4l.c v4l.h libunicap/cpi/v4l/v4l.h0000644000175000017500000000345013164711411015415 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __V4L_H__ #define __V4L_H__ #include #include struct _v4l_handle { char device[512]; int fd; struct video_capability v4lcap; struct video_picture v4lpict; struct video_picture v4lpict_default; struct video_mbuf v4lmbuf; struct video_window v4lwindow; unsigned int palette[32]; unicap_format_t current_format; void *map; int queued_buffer; int ready_buffer; struct _unicap_queue *in_queue; unsigned int in_queue_lock; struct _unicap_queue *out_queue; unsigned int out_queue_lock; int capture_running; pthread_t capture_thread; int quit_capture_thread; sem_t sema; sem_t out_sema; unicap_event_callback_t event_callback; unicap_handle_t unicap_handle; }; typedef struct _v4l_handle *v4l_handle_t; #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)a))+(((unsigned int)b)<<8)+(((unsigned int)c)<<16)+(((unsigned int)d)<<24)) #endif//__V4L_H__ libunicap/cpi/v4l/v4l.c0000644000175000017500000006533713164711411015424 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if V4L_DEBUG #define DEBUG #endif #include #include #include // for v4l2 checks #include "v4l.h" unsigned int v4l_palette_array[] = { VIDEO_PALETTE_GREY, VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB555, VIDEO_PALETTE_RGB24, VIDEO_PALETTE_RGB32, VIDEO_PALETTE_YUV422, VIDEO_PALETTE_YUYV, VIDEO_PALETTE_UYVY, VIDEO_PALETTE_YUV420, VIDEO_PALETTE_YUV411, VIDEO_PALETTE_RAW, VIDEO_PALETTE_YUV422P, VIDEO_PALETTE_YUV411P, }; static unicap_status_t v4l_enumerate_devices( unicap_device_t *device, int index ); static unicap_status_t v4l_open( void **cpi_data, unicap_device_t *device ); static unicap_status_t v4l_close( void *cpi_data ); static unicap_status_t v4l_reenumerate_formats( void *cpi_data, int *count ); static unicap_status_t v4l_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ); static unicap_status_t v4l_set_format( void *cpi_data, unicap_format_t *format ); static unicap_status_t v4l_get_format( void *cpi_data, unicap_format_t *format ); static unicap_status_t v4l_reenumerate_properties( void *cpi_data, int *count ); static unicap_status_t v4l_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ); static unicap_status_t v4l_set_property( void *cpi_data, unicap_property_t *property ); static unicap_status_t v4l_get_property( void *cpi_data, unicap_property_t *property ); static unicap_status_t v4l_capture_start( void *cpi_data ); static unicap_status_t v4l_capture_stop( void *cpi_data ); static unicap_status_t v4l_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ); static unicap_status_t v4l_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); static unicap_status_t v4l_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ); static unicap_status_t v4l_poll_buffer( void *cpi_data, int *count ); static unicap_status_t v4l_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ); static void v4l_capture_thread( v4l_handle_t handle ); static int queue_buffer( v4l_handle_t v4lhandle, int b ); static struct _unicap_cpi cpi_s = { cpi_version: 1<<16, cpi_capabilities: 0x3ffff, cpi_enumerate_devices: v4l_enumerate_devices, cpi_open: v4l_open, cpi_close: v4l_close, cpi_reenumerate_formats: v4l_reenumerate_formats, cpi_enumerate_formats: v4l_enumerate_formats, cpi_set_format: v4l_set_format, cpi_get_format: v4l_get_format, cpi_reenumerate_properties: v4l_reenumerate_properties, cpi_enumerate_properties: v4l_enumerate_properties, cpi_set_property: v4l_set_property, cpi_get_property: v4l_get_property, cpi_capture_start: v4l_capture_start, cpi_capture_stop: v4l_capture_stop, cpi_queue_buffer: v4l_queue_buffer, cpi_dequeue_buffer: v4l_dequeue_buffer, cpi_wait_buffer: v4l_wait_buffer, cpi_poll_buffer: v4l_poll_buffer, cpi_set_event_notify: v4l_set_event_notify, }; #if ENABLE_STATIC_CPI void unicap_v4l_register_static_cpi( struct _unicap_cpi **cpi ) { *cpi = &cpi_s; } #else unicap_status_t cpi_register( struct _unicap_cpi *reg_data ) { memcpy( reg_data, &cpi_s, sizeof( struct _unicap_cpi ) ); /* reg_data->cpi_version = 1<<16; */ /* reg_data->cpi_capabilities = 0x3ffff; */ /* reg_data->cpi_enumerate_devices = v4l_enumerate_devices; */ /* reg_data->cpi_open = v4l_open; */ /* reg_data->cpi_close = v4l_close; */ /* reg_data->cpi_reenumerate_formats = v4l_reenumerate_formats; */ /* reg_data->cpi_enumerate_formats = v4l_enumerate_formats; */ /* reg_data->cpi_set_format = v4l_set_format; */ /* reg_data->cpi_get_format = v4l_get_format; */ /* reg_data->cpi_reenumerate_properties = v4l_reenumerate_properties; */ /* reg_data->cpi_enumerate_properties = v4l_enumerate_properties; */ /* reg_data->cpi_set_property = v4l_set_property; */ /* reg_data->cpi_get_property = v4l_get_property; */ /* reg_data->cpi_capture_start = v4l_capture_start; */ /* reg_data->cpi_capture_stop = v4l_capture_stop; */ /* reg_data->cpi_queue_buffer = v4l_queue_buffer; */ /* reg_data->cpi_dequeue_buffer = v4l_dequeue_buffer; */ /* reg_data->cpi_wait_buffer = v4l_wait_buffer; */ /* reg_data->cpi_poll_buffer = v4l_poll_buffer; */ /* reg_data->cpi_set_event_notify = v4l_set_event_notify; */ return STATUS_SUCCESS; } #endif//ENABLE_STATIC_CPI static int file_filter( const struct dirent *a ) { int match = 0; // match: 'videoXY' where X = {0..9} and Y = {0..9} if( !strncmp( a->d_name, "video", 5 ) ) { if( strlen( a->d_name ) > 5 ) { if( ( a->d_name[5] >= '0' ) && ( a->d_name[5] <= '9' ) ) // match // the 'X' { match = 1; } if( strlen( a->d_name ) > 6 ) { match = 0; if( ( a->d_name[6] >= '0' ) && ( a->d_name[6] <= '9' ) ) { match = 1; } } if( strlen( a->d_name ) > 7 ) { match = 0; } } } return match; } static unicap_status_t v4l_enumerate_devices( unicap_device_t *device, int index ) { int fd; char devname[256]; struct dirent **namelist; int n; int found = -1; struct video_capability v4lcap; struct v4l2_capability v4l2caps; TRACE( "*** v4l enumerate devices\n" ); n = scandir( "/dev", &namelist, file_filter, alphasort ); if( n < 0 ) { TRACE( "Failed to scan directory '/dev' \n" ); return STATUS_NO_DEVICE; } while( ( found != index ) && n-- ) { sprintf( devname, "/dev/%s", namelist[n]->d_name ); /* free( namelist[n]->d_name ); */ TRACE( "v4l: open %s\n", devname ); if( ( fd = open( devname, O_RDONLY | O_NONBLOCK ) ) == -1 ) { TRACE( "v4l_cpi: open(%s): %s\n", devname, strerror( errno ) ); continue; } if( ioctl( fd, VIDIOC_QUERYCAP, &v4l2caps ) == 0 && (v4l2caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { TRACE( "v4l2 ioctls succeeded\n" ); close( fd ); continue; } /* if( (v4l2caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) ) */ /* { */ /* // v4l version two device */ /* close( fd ); */ /* continue; */ /* } */ if( ioctl( fd, VIDIOCGCAP, &v4lcap ) < 0 ) { TRACE( "VIDIOCGCAP ioctl failed!\n" ); close( fd ); continue; } if( !(v4lcap.type & VID_TYPE_CAPTURE ) ) { // no capture to memory capability close( fd ); continue; } found++; close( fd ); } /* free( namelist ); */ if( found != index ) { return STATUS_NO_DEVICE; } sprintf( device->identifier, "%s [%d]", v4lcap.name, index ); strcpy( device->device, devname ); strcpy( device->model_name, v4lcap.name ); strcpy( device->vendor_name, "v4l" ); device->model_id = 1; device->vendor_id = 0xffff0000; device->flags = UNICAP_CPI_SERIALIZED; return STATUS_SUCCESS; } static unicap_status_t v4l_open( void **cpi_data, unicap_device_t *device ) { v4l_handle_t v4lhandle; *cpi_data = malloc( sizeof( struct _v4l_handle ) ); if( !*cpi_data ) { TRACE( "malloc failed\n" ); return STATUS_FAILURE; } v4lhandle = *cpi_data; memset( v4lhandle, 0x0, sizeof( struct _v4l_handle ) ); if( sem_init( &v4lhandle->sema, 0, 1 ) ) { TRACE( "sem_init failed\n" ); free( v4lhandle ); return STATUS_FAILURE; } if( sem_init( &v4lhandle->out_sema, 0, 0 ) ) { TRACE( "sem_init failed!\n" ); sem_destroy( &v4lhandle->sema ); free( v4lhandle ); return STATUS_FAILURE; } v4lhandle->fd = open( device->device, O_RDWR ); if( v4lhandle->fd == -1 ) { TRACE( "open failed, device = %s\n", device->device ); TRACE( "error was: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( ioctl( v4lhandle->fd, VIDIOCGCAP, &v4lhandle->v4lcap ) ) { // failed v4l ioctl, look for next device close( v4lhandle->fd ); return STATUS_FAILURE; } v4l_reenumerate_formats( v4lhandle, NULL ); v4l_reenumerate_properties( v4lhandle, NULL ); v4lhandle->in_queue = ucutil_queue_new(); v4lhandle->out_queue = ucutil_queue_new(); return STATUS_SUCCESS; } static unicap_status_t v4l_close( void *cpi_data ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; close( v4lhandle->fd ); sem_destroy( &v4lhandle->sema ); sem_destroy( &v4lhandle->out_sema ); if( v4lhandle->unicap_handle ) { // handle is a copy!! free( v4lhandle->unicap_handle ); } free( v4lhandle ); return STATUS_SUCCESS; } static unicap_status_t v4l_reenumerate_formats( void *cpi_data, int *_pcount ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; struct video_picture v4lpict; int count = 0; int p_count = sizeof( v4l_palette_array ) / sizeof( unsigned int ); int i; if( ioctl( v4lhandle->fd, VIDIOCGPICT, &v4lhandle->v4lpict ) ) { TRACE( "ioctl failed\n" ); return STATUS_FAILURE; } memset( &v4lhandle->palette, 0x0, 32 * sizeof( unsigned int ) ); memcpy( &v4lpict, &v4lhandle->v4lpict, sizeof( struct video_picture ) ); for( i = 0; i < p_count; i++ ) { v4lpict.palette = v4l_palette_array[i]; TRACE( "try palette: %d\n", v4lpict.palette ); if( !ioctl( v4lhandle->fd, VIDIOCSPICT, &v4lpict ) ) { TRACE( "succeeded palette: %d\n", v4lpict.palette ); v4lhandle->palette[i] = v4lpict.palette; count++; } } if( _pcount ) { *_pcount = count; } return STATUS_SUCCESS; } static unicap_status_t v4l_enumerate_formats( void *cpi_data, unicap_format_t *format, int index ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; unsigned int p = 0xffffffff; int p_count = sizeof( v4l_palette_array ) / sizeof( unsigned int ); int i, j = -1; int tmp; if( v4lhandle->v4lpict.palette == 0 ) { v4l_reenumerate_formats( cpi_data, &tmp ); } for( i = 0; i < p_count; i++ ) { if( v4lhandle->palette[i] ) { j++; } if( j == index ) { p = v4lhandle->palette[i]; TRACE( "p: %d\n", p ); break; } } if( p == 0xffffffff ) { return STATUS_NO_MATCH; } switch( p ) { case VIDEO_PALETTE_GREY: strcpy( format->identifier, "Grey ( Mono 8pp )" ); format->fourcc = FOURCC( 'G', 'R', 'E', 'Y' ); format->bpp = 8; break; case VIDEO_PALETTE_HI240: strcpy( format->identifier, "HI240 Bt848 8Bit color cube" ); format->fourcc = FOURCC( 'H', '2', '4', '0' ); format->bpp = 8; break; case VIDEO_PALETTE_RGB565: strcpy( format->identifier, "RGB 16bpp" ); format->fourcc = FOURCC( 'R', 'G', 'B', '6' ); format->bpp = 16; break; case VIDEO_PALETTE_RGB555: strcpy( format->identifier, "RGB 15bpp" ); format->fourcc = FOURCC( 'R', 'G', 'B', '5' ); format->bpp = 15; break; case VIDEO_PALETTE_RGB24: strcpy( format->identifier, "BGR 24bpp" ); format->fourcc = FOURCC( 'B', 'G', 'R', '3' ); format->bpp = 24; break; case VIDEO_PALETTE_RGB32: strcpy( format->identifier, "RGB 32bpp" ); format->fourcc = FOURCC( 'R', 'G', 'B', '4' ); format->bpp = 32; break; case VIDEO_PALETTE_YUV422: strcpy( format->identifier, "YUV 4:2:2" ); format->fourcc = FOURCC( 'Y', '4', '2', '2' ); format->bpp = 16; break; case VIDEO_PALETTE_YUYV: strcpy( format->identifier, "YUYV" ); format->fourcc = FOURCC( 'Y', 'U', 'Y', 'V' ); format->bpp = 16; break; case VIDEO_PALETTE_UYVY: strcpy( format->identifier, "UYVY" ); format->fourcc = FOURCC( 'U', 'Y', 'V', 'Y' ); format->bpp = 16; break; case VIDEO_PALETTE_YUV420: strcpy( format->identifier, "Y 4:2:0" ); format->fourcc = FOURCC( 'Y', '4', '2', '0' ); format->bpp = 16; break; case VIDEO_PALETTE_YUV411: strcpy( format->identifier, "Y 4:1:1" ); format->fourcc = FOURCC( 'Y', '4', '1', '1' ); format->bpp = 12; break; case VIDEO_PALETTE_RAW: strcpy( format->identifier, "Bt848 raw format" ); format->fourcc = FOURCC( 'R', 'A', 'W', ' ' ); format->bpp = 8; break; case VIDEO_PALETTE_YUV422P: strcpy( format->identifier, "Y 4:2:2 planar" ); format->fourcc = FOURCC( 'Y', '4', '2', 'P' ); format->bpp = 16; break; case VIDEO_PALETTE_YUV411P: strcpy( format->identifier, "Y 4:1:1 planar" ); format->fourcc = FOURCC( '4', '1', '1', 'P' ); format->bpp = 12; break; default: TRACE( "unknown format / wrong index\n" ); return STATUS_FAILURE; } format->size.width = v4lhandle->v4lcap.maxwidth; format->size.height = v4lhandle->v4lcap.maxheight; format->min_size.width = v4lhandle->v4lcap.minwidth; format->max_size.width = v4lhandle->v4lcap.maxwidth; format->min_size.height = v4lhandle->v4lcap.minheight; format->max_size.height = v4lhandle->v4lcap.maxheight; format->buffer_size = format->size.width * format->size.height * format->bpp / 8; format->sizes = 0; format->size_count = 0; format->h_stepping = 0; format->v_stepping = 0; #ifdef DEBUG TRACE( "bsize: %d, wxhxb: %dx%dx%d\n", format->buffer_size, format->size.width, format->size.height, format->bpp ); { char str[1024]; int s = 1024; unicap_describe_format( format, str, &s ); printf( str ); } #endif return STATUS_SUCCESS; } static unicap_status_t v4l_set_format( void *cpi_data, unicap_format_t *format ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; unsigned int p; switch( format->fourcc ) { case FOURCC( 'G', 'R', 'E', 'Y' ): p = VIDEO_PALETTE_GREY; break; case FOURCC( 'H', '2', '4', '0' ): p = VIDEO_PALETTE_HI240; break; case FOURCC( 'R', 'G', 'B', '6' ): p = VIDEO_PALETTE_RGB565; break; case FOURCC( 'R', 'G', 'B', '5' ): p = VIDEO_PALETTE_RGB555; break; case FOURCC( 'B', 'G', 'R', '3' ): p = VIDEO_PALETTE_RGB24; break; case FOURCC( 'R', 'G', 'B', '4' ): p = VIDEO_PALETTE_RGB32; break; case FOURCC( 'Y', '4', '2', '2' ): p = VIDEO_PALETTE_YUV422; break; case FOURCC( 'Y', 'U', 'Y', 'V' ): p = VIDEO_PALETTE_YUYV; break; case FOURCC( 'U', 'Y', 'V', 'Y' ): p = VIDEO_PALETTE_UYVY; break; case FOURCC( 'Y', '4', '2', '0' ): p = VIDEO_PALETTE_YUV420; break; case FOURCC( 'Y', '4', '1', '1' ): p = VIDEO_PALETTE_YUV411; break; case FOURCC( 'R', 'A', 'W', ' ' ): p = VIDEO_PALETTE_RAW; break; case FOURCC( 'Y', '4', '2', 'P' ): p = VIDEO_PALETTE_YUV422P; break; case FOURCC( '4', '1', '1', 'P' ): p = VIDEO_PALETTE_YUV411P; break; default: TRACE( "set format with unknown fourcc\n" ); return STATUS_FAILURE; break; } // get current settings for brightness etc. if( ioctl( v4lhandle->fd, VIDIOCGPICT, &v4lhandle->v4lpict ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } v4lhandle->v4lpict.palette = p; v4lhandle->v4lpict.depth = format->bpp; TRACE( "ioctl VIDIOCSPICT\n" ); if( ioctl( v4lhandle->fd, VIDIOCSPICT, &v4lhandle->v4lpict ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); TRACE( "p: %d\n", v4lhandle->v4lpict.palette ); return STATUS_FAILURE; } if( ioctl( v4lhandle->fd, VIDIOCGPICT, &v4lhandle->v4lpict ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); TRACE( "p: %d\n", v4lhandle->v4lpict.palette ); return STATUS_FAILURE; } TRACE( "result: depth: %d palette: %d\n", v4lhandle->v4lpict.depth, v4lhandle->v4lpict.palette ); memset( &v4lhandle->v4lwindow, 0x0, sizeof( struct video_window ) ); v4lhandle->v4lwindow.width = format->size.width; v4lhandle->v4lwindow.height = format->size.height; TRACE( "ioctl VIDIOCSWIN size: %dx%d\n", v4lhandle->v4lwindow.width, v4lhandle->v4lwindow.height ); if( ioctl( v4lhandle->fd, VIDIOCSWIN, &v4lhandle->v4lwindow ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( ioctl( v4lhandle->fd, VIDIOCGWIN, &v4lhandle->v4lwindow ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } TRACE( "succeeded: size: %dx%d \n", v4lhandle->v4lwindow.x, v4lhandle->v4lwindow.y ); unicap_copy_format( &v4lhandle->current_format, format ); return STATUS_SUCCESS; } static unicap_status_t v4l_get_format( void *cpi_data, unicap_format_t *format ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; memcpy( format, &v4lhandle->current_format, sizeof( unicap_format_t ) ); return STATUS_SUCCESS; } static unicap_status_t v4l_reenumerate_properties( void *cpi_data, int *_pcount ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; if( ioctl( v4lhandle->fd, VIDIOCGPICT, &v4lhandle->v4lpict_default ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( _pcount ) { *_pcount = 5; } return STATUS_SUCCESS; } static unicap_status_t v4l_enumerate_properties( void *cpi_data, unicap_property_t *property, int index ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; memset( property, 0x0, sizeof( unicap_property_t ) ); switch( index ) { case 0: strcpy( property->identifier, "brightness" ); property->value = v4lhandle->v4lpict_default.brightness; break; case 1: strcpy( property->identifier, "hue" ); property->value = v4lhandle->v4lpict_default.hue; break; case 2: strcpy( property->identifier, "colour" ); property->value = v4lhandle->v4lpict_default.colour; break; case 3: strcpy( property->identifier, "contrast" ); property->value = v4lhandle->v4lpict_default.contrast; break; case 4: strcpy( property->identifier, "whiteness" ); property->value = v4lhandle->v4lpict_default.whiteness; break; default: return STATUS_NO_MATCH; } property->range.min = 0.0f; property->range.max = 1.0f; property->value = property->value / 65535.0f; property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; property->stepping = 1.0f/256.0f; strcpy( property->category, "video" ); return STATUS_SUCCESS; } static unicap_status_t v4l_set_property( void *cpi_data, unicap_property_t *property ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; int value = property->value * 65535; if( !strcmp( property->identifier, "brightness" ) ) { v4lhandle->v4lpict.brightness = value; } else if( !strcmp( property->identifier, "hue" ) ) { v4lhandle->v4lpict.hue = value; } else if( !strcmp( property->identifier, "colour" ) ) { v4lhandle->v4lpict.colour = value; } else if( !strcmp( property->identifier, "contrast" ) ) { v4lhandle->v4lpict.contrast = value; } else if( !strcmp( property->identifier, "whiteness" ) ) { v4lhandle->v4lpict.whiteness = value; } else { return STATUS_FAILURE; } if( ioctl( v4lhandle->fd, VIDIOCSPICT, &v4lhandle->v4lpict ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } return STATUS_SUCCESS; } static unicap_status_t v4l_get_property( void *cpi_data, unicap_property_t *property ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; double value; if( ioctl( v4lhandle->fd, VIDIOCGPICT, &v4lhandle->v4lpict ) ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } if( !strcmp( property->identifier, "brightness" ) ) { value = v4lhandle->v4lpict.brightness; } else if( !strcmp( property->identifier, "hue" ) ) { value = v4lhandle->v4lpict.hue; } else if( !strcmp( property->identifier, "colour" ) ) { value = v4lhandle->v4lpict.colour; } else if( !strcmp( property->identifier, "contrast" ) ) { value = v4lhandle->v4lpict.contrast; } else if( !strcmp( property->identifier, "whiteness" ) ) { value = v4lhandle->v4lpict.whiteness; } else { return STATUS_FAILURE; } property->range.min = 0.0f; property->range.max = 1.0f; property->value = value / 65535.0f; property->flags = UNICAP_FLAGS_MANUAL; property->flags_mask = UNICAP_FLAGS_MANUAL; property->stepping = 1.0f/256.0f; strcpy( property->category, "video" ); return STATUS_SUCCESS; } static unicap_status_t v4l_capture_start( void *cpi_data ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; int i; if( ioctl( v4lhandle->fd, VIDIOCGMBUF, &v4lhandle->v4lmbuf ) == -1 ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return STATUS_FAILURE; } TRACE( "mbuf: size: %d, frames: %d\n", v4lhandle->v4lmbuf.size, v4lhandle->v4lmbuf.frames ); for( i = 0; i < v4lhandle->v4lmbuf.frames; i++ ) { TRACE( "offset %d: %x\n", i, v4lhandle->v4lmbuf.offsets[i] ); } v4lhandle->map = mmap( 0, v4lhandle->v4lmbuf.size, PROT_WRITE | PROT_READ, MAP_SHARED, v4lhandle->fd, 0 ); if( v4lhandle->map == MAP_FAILED ) { /* ERROR( "mmap failed: %s\nCapture can not start!\n", strerror( errno ) ); */ return STATUS_FAILURE; } TRACE( "map: %p\n", v4lhandle->map ); v4lhandle->ready_buffer = -1; for( i = 0; i < v4lhandle->v4lmbuf.frames; i++ ) { queue_buffer( v4lhandle, i ); } v4lhandle->quit_capture_thread = 0; pthread_create( &v4lhandle->capture_thread, NULL, (void*(*)(void*))v4l_capture_thread, v4lhandle ); v4lhandle->capture_running = 1; return STATUS_SUCCESS; } static unicap_status_t v4l_capture_stop( void *cpi_data ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; if( v4lhandle->capture_running ) { v4lhandle->quit_capture_thread = 1; sem_post( &v4lhandle->out_sema ); pthread_join( v4lhandle->capture_thread, NULL ); if( v4lhandle->map ) { munmap( v4lhandle->map, v4lhandle->v4lmbuf.size ); v4lhandle->map = 0; } v4lhandle->capture_running = 0; } return STATUS_SUCCESS; } static unicap_status_t v4l_queue_buffer( void *cpi_data, unicap_data_buffer_t *buffer ) { v4l_handle_t v4lhandle = ( v4l_handle_t ) cpi_data; struct _unicap_queue *entry; entry = malloc( sizeof( unicap_queue_t ) ); entry->data = buffer; ucutil_insert_back_queue( v4lhandle->in_queue, entry ); return STATUS_SUCCESS; } static unicap_status_t v4l_dequeue_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { v4l_handle_t handle = ( v4l_handle_t ) cpi_data; TRACE( "dequeue buffer\n" ); if( handle->capture_running ) { TRACE( "dequeue while capturing\n" ); return STATUS_FAILURE; } return STATUS_NOT_IMPLEMENTED; } static unicap_status_t v4l_wait_buffer( void *cpi_data, unicap_data_buffer_t **buffer ) { v4l_handle_t handle = ( v4l_handle_t ) cpi_data; unicap_status_t status = STATUS_FAILURE; *buffer = NULL; if( !handle->out_queue->next &&! handle->capture_running ) { TRACE( "Wait->capture stopped" ); return STATUS_IS_STOPPED; } sem_wait( &handle->out_sema ); if( handle->out_queue->next ) { unicap_data_buffer_t *returned_buffer; struct _unicap_queue *entry; entry = ucutil_get_front_queue( handle->out_queue ); returned_buffer = ( unicap_data_buffer_t * ) entry->data; free( entry ); *buffer = returned_buffer; status = STATUS_SUCCESS; } return status; } static unicap_status_t v4l_poll_buffer( void *data, int *count ) { TRACE( "poll buffer\n" ); return STATUS_NOT_IMPLEMENTED; } static unicap_status_t v4l_set_event_notify( void *cpi_data, unicap_event_callback_t func, unicap_handle_t unicap_handle ) { v4l_handle_t handle = ( v4l_handle_t )cpi_data; handle->event_callback = func; handle->unicap_handle = unicap_handle; return STATUS_SUCCESS; } static int queue_buffer( v4l_handle_t v4lhandle, int buffer ) { struct video_mmap v4lmmap; int frame; frame = buffer; TRACE( "queue buffer, frame: %d\n", frame ); v4lmmap.frame = frame; v4lmmap.width = v4lhandle->current_format.size.width; v4lmmap.height = v4lhandle->current_format.size.height; v4lmmap.format = v4lhandle->v4lpict.palette; if( ioctl( v4lhandle->fd, VIDIOCMCAPTURE, &v4lmmap ) == -1 ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return 0; } return 1; } static int wait_buffer( v4l_handle_t v4lhandle, unicap_data_buffer_t *data_buffer ) { int frame; v4lhandle->ready_buffer = ( v4lhandle->ready_buffer + 1 ) % v4lhandle->v4lmbuf.frames; frame = v4lhandle->ready_buffer; TRACE( "wait buffer, frame: %d\n", frame ); if( ioctl( v4lhandle->fd, VIDIOCSYNC, &frame ) == -1 ) { TRACE( "ioctl failed: %s\n", strerror( errno ) ); return 0; } data_buffer->data = v4lhandle->map + v4lhandle->v4lmbuf.offsets[frame]; gettimeofday( &data_buffer->fill_time, NULL ); return 1; } static void v4l_capture_thread( v4l_handle_t handle ) { unicap_data_buffer_t new_frame_buffer; unicap_copy_format( &new_frame_buffer.format, &handle->current_format ); new_frame_buffer.buffer_size = handle->current_format.buffer_size; new_frame_buffer.type = UNICAP_BUFFER_TYPE_SYSTEM; while( !handle->quit_capture_thread ) { unicap_queue_t *entry; if( sem_wait( &handle->sema ) ) { TRACE( "SEM_WAIT_FAILED" ); } if( !wait_buffer( handle, &new_frame_buffer ) ) { sem_post( &handle->sema ); continue; } sem_post( &handle->sema ); if( handle->event_callback ) { handle->event_callback( handle->unicap_handle, UNICAP_EVENT_NEW_FRAME, &new_frame_buffer ); } entry = ucutil_get_front_queue( handle->in_queue ); if( entry ) { unicap_data_buffer_t *data_buffer = ( unicap_data_buffer_t * ) entry->data; struct _unicap_queue *outentry = malloc( sizeof( unicap_queue_t ) ); free( entry ); data_buffer->buffer_size = new_frame_buffer.buffer_size; unicap_copy_format( &data_buffer->format, &new_frame_buffer.format ); if( data_buffer->type == UNICAP_BUFFER_TYPE_SYSTEM ) { data_buffer->data = new_frame_buffer.data; } else { memcpy( data_buffer->data, new_frame_buffer.data, new_frame_buffer.buffer_size ); } outentry->data = data_buffer; memcpy( &data_buffer->fill_time, &new_frame_buffer.fill_time, sizeof( struct timeval ) ); ucutil_insert_back_queue( handle->out_queue, outentry ); sem_post( &handle->out_sema ); } if( sem_wait( &handle->sema ) ) { TRACE( "SEM_WAIT_FAILED\n" ); } queue_buffer( handle, handle->ready_buffer ); sem_post( &handle->sema ); } } libunicap/debian/0000755000175000017500000000000013164711411014477 5ustar zmoelnigzmoelniglibunicap/debian/libunicap-dev.dirs0000644000175000017500000000005513164711411020104 0ustar zmoelnigzmoelnigusr/include/unicap usr/lib usr/lib/pkgconfig libunicap/debian/compat0000644000175000017500000000000213164711411015675 0ustar zmoelnigzmoelnig7 libunicap/debian/libunicap2.dirs0000644000175000017500000000007513164711411017414 0ustar zmoelnigzmoelnigusr/lib usr/lib/unicap2 usr/lib/unicap2/cpi usr/share/locale libunicap/debian/deletable.files0000644000175000017500000000000013164711411017432 0ustar zmoelnigzmoelniglibunicap/debian/libunicap-doc.install0000644000175000017500000000004313164711411020575 0ustar zmoelnigzmoelnigusr/share/gtk-doc/html/libunicap/* libunicap/debian/libunicap-dev.install0000644000175000017500000000025313164711411020611 0ustar zmoelnigzmoelnigusr/include/unicap/unicap.h usr/include/unicap/unicap_status.h usr/include/unicap/unicap_version.h usr/lib/libunicap.a usr/lib/libunicap.so usr/lib/pkgconfig/libunicap.pc libunicap/debian/changelog0000644000175000017500000000242213164711411016351 0ustar zmoelnigzmoelniglibunicap (0.9.13) lucid; urgency=low * updated to 0.9.13 -- Arne Caspari Thu, 07 Oct 2010 22:29:42 +0200 libunicap (0.9.12) lucid; urgency=low * updated to 0.9.12 -- Arne Caspari Sun, 19 Sep 2010 09:20:35 +0200 libunicap (0.9.11-3) lucid; urgency=low * fix missing dirs and install -- Arne Caspari Sat, 18 Sep 2010 19:26:05 +0200 libunicap (0.9.11-2) lucid; urgency=low * fixed dependency version -- Arne Caspari Sat, 18 Sep 2010 19:02:03 +0200 libunicap (0.9.11-1) lucid; urgency=low * renamed dev package to libunicap2-dev -- Arne Caspari Sat, 18 Sep 2010 18:23:59 +0200 libunicap (0.9.11) lucid; urgency=low * updated to 0.9.11 -- Arne Caspari Thu, 16 Sep 2010 18:06:34 +0200 libunicap (0.9.10) lucid; urgency=low * updated to 0.9.10 -- Arne Caspari Wed, 26 May 2010 21:54:23 +0200 libunicap (0.9.9) karmic; urgency=low * added euvccam cpi -- Arne Caspari Wed, 24 Mar 2010 14:19:49 +0100 libunicap (0.9.8) karmic; urgency=low * initial PPA package -- Arne Caspari Sun, 17 Jan 2010 13:06:11 +0100 libunicap/debian/libunicap2-dev.install0000644000175000017500000000025313164711411020673 0ustar zmoelnigzmoelnigusr/include/unicap/unicap.h usr/include/unicap/unicap_status.h usr/include/unicap/unicap_version.h usr/lib/libunicap.a usr/lib/libunicap.so usr/lib/pkgconfig/libunicap.pc libunicap/debian/libunicap2.install0000644000175000017500000000010713164711411020115 0ustar zmoelnigzmoelnigusr/lib/libunicap.so.* usr/lib/unicap2/cpi/lib*.so* usr/share/locale/* libunicap/debian/copyright0000644000175000017500000000204413164711411016432 0ustar zmoelnigzmoelnigunicap: Copyright 2008 Arne Caspari This package was debianized by Sven Neumann Thu May 4 12:23:33 CEST 2006 It was downloaded from http://unicap-imaging.org/download.htm Copyright: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. On Debian GNU/Linux systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. libunicap/debian/rules0000755000175000017500000000426613164711411015567 0ustar zmoelnigzmoelnig#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 # These are used for cross-compiling and for saving the configure script # from having to guess our platform (since we know it already) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif config.status: configure dh_testdir # Add here commands to configure the package. ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --enable-gtk-doc build: build-stamp build-stamp: config.status dh_testdir # Add here commands to compile the package. $(MAKE) touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp # Add here commands to clean up after the build process. [ ! -f Makefile ] || $(MAKE) distclean ifneq "$(wildcard /usr/share/misc/config.sub)" "" cp -f /usr/share/misc/config.sub config.sub endif ifneq "$(wildcard /usr/share/misc/config.guess)" "" cp -f /usr/share/misc/config.guess config.guess endif dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/unicap. $(MAKE) install DESTDIR=$(CURDIR)/debian/unicap # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs ChangeLog dh_installdocs dh_install --sourcedir=debian/unicap dh_installman dh_link dh_strip dh_compress dh_fixperms dh_makeshlibs dh_shlibdeps dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install libunicap/debian/libunicap2-dev.dirs0000644000175000017500000000005513164711411020166 0ustar zmoelnigzmoelnigusr/include/unicap usr/lib usr/lib/pkgconfig libunicap/debian/libunicap-doc.dirs0000644000175000017500000000012413164711411020070 0ustar zmoelnigzmoelnigusr/share usr/share/gtk-doc usr/share/gtk-doc/html usr/share/gtk-doc/html/libunicap libunicap/debian/control0000644000175000017500000000230213164711411016077 0ustar zmoelnigzmoelnigSource: libunicap Section: libs Priority: optional Maintainer: Arne Caspari Build-Depends: debhelper (>= 7), autotools-dev, libraw1394-dev, libtheora-dev, gtk-doc-tools, libasound2-dev, libvorbis-dev, libtool Standards-Version: 3.8.3 Package: libunicap2 Section: libs Architecture: any Depends: ${shlibs:Depends} Conflicts: libunicap-0 Description: a library to access different kinds of video capture devices . This package provides unicap, a video capture library. Package: libunicap2-dev Section: libdevel Architecture: any Depends: libunicap2 (= ${binary:Version}), libraw1394-dev, pkg-config Conflicts: libunicap-dev Description: unicap library, development files . This package contains the files needed to compile and link programs which use libunicap. Package: libunicap-doc Section: doc Architecture: any Description: unicap library, documentation . This package provides the API documentation for libunicap. Package: libunicap-2 Section: misc Architecture: any Depends: libunicap2 (= ${binary:Version}) Description: transitional package for libunicap2 . This package is a transitional package. It could be removed after the installation of the libunicap2 package. libunicap/README0000644000175000017500000000406613164711411014143 0ustar zmoelnigzmoelnigunicap is a library to access different kinds of ( video ) capture devices. It uses a .so loading mechanism for the device layers so new device drivers can easily be added. unicap provides a simple yet flexible and powerfull API. The capture application is able to access very different kinds of capture devices and set all of their properties ( such as brightness/contrast... ) without the exact knowledge of the device. Currently unicap provides support for IIDC cameras, video-4-linux, video-4-linux-2 and video-to-firewire converters. /Arne Caspari ------------------------------------------------ REQUIREMENTS: * Gtk+ 2.0 or newer for libunicapgtk * libraw1394 0.10.0 or newer for dcam or vid21394 plugins QUICKSTART: * Have a look at the examples subdirectory! Note: Currently the examples expect the device to deliver UYVY color format * run the sdl_display example at first to see if you can get a live video with your video capture device EXAMPLES: Note: unicap needs to be installed with 'make install' to be able to compile these examples * sdl_display: Display a live video image using the SDL library * xv_display: Displays a live video image using the Xv extension of the X server. This example comes in it's own .tar.gz archive and has it's own configure script. Untar the xv_display-x.y.z.tar.gz file in any directory after installing unicap and run the usual './configure && make' * device_info: Lists all devices and properties. Use this to get an idea how properties ( ie. brightnes, contrast etc ) work. * unicapgtk_*: These examples use the GTK+ widget. KNOWN LIMITATIONS: * v4l and v4l2 support is rudimentary. Tuners are currently not supported. * Time stamping might be inaccurate, depending on the plugin used to access the device QUESTIONS / FEEDBACK: Provide feedback about working / not working devices and patches Please contact me at arne@unicap-imaging.org libunicap/gtk-doc.make0000644000175000017500000001364213164711411015452 0ustar zmoelnigzmoelnig# -*- mode: makefile -*- #################################### # Everything below here is generic # #################################### if GTK_DOC_USE_LIBTOOL GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) GTKDOC_RUN = $(LIBTOOL) --mode=execute else GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) GTKDOC_RUN = sh -c endif # We set GPATH here; this gives us semantics for GNU make # which are more like other make's VPATH, when it comes to # whether a source that is a target of one rule is then # searched for in VPATH/GPATH. # GPATH = $(srcdir) TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) EXTRA_DIST = \ $(content_files) \ $(HTML_IMAGES) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \ $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp SCANOBJ_FILES = \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ $(DOC_MODULE).prerequisites \ $(DOC_MODULE).signals REPORT_FILES = \ $(DOC_MODULE)-undocumented.txt \ $(DOC_MODULE)-undeclared.txt \ $(DOC_MODULE)-unused.txt CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) if ENABLE_GTK_DOC all-local: html-build.stamp else all-local: endif docs: html-build.stamp $(REPORT_FILES): sgml-build.stamp #### scan #### scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) @echo 'gtk-doc: Scanning header files' @-chmod -R u+w $(srcdir) cd $(srcdir) && \ gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ else \ cd $(srcdir) ; \ for i in $(SCANOBJ_FILES) ; do \ test -f $$i || touch $$i ; \ done \ fi touch scan-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp @true #### templates #### tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt @echo 'gtk-doc: Rebuilding template files' @-chmod -R u+w $(srcdir) cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS) touch tmpl-build.stamp tmpl.stamp: tmpl-build.stamp @true tmpl/*.sgml: @true #### xml #### sgml-build.stamp: tmpl.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files) @echo 'gtk-doc: Building XML' @-chmod -R u+w $(srcdir) cd $(srcdir) && \ gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS) touch sgml-build.stamp sgml.stamp: sgml-build.stamp @true #### html #### html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) @echo 'gtk-doc: Building HTML' @-chmod -R u+w $(srcdir) rm -rf $(srcdir)/html mkdir $(srcdir)/html mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ if test "$(?)" = "0"; then \ mkhtml_options=--path="$(srcdir)"; \ fi cd $(srcdir)/html && gtkdoc-mkhtml $(mkhtml_options) $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html ) @echo 'gtk-doc: Fixing cross-references' cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) touch html-build.stamp ############## clean-local: rm -f *~ *.bak rm -rf .libs distclean-local: cd $(srcdir) && \ rm -rf xml $(REPORT_FILES) \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt maintainer-clean-local: clean cd $(srcdir) && rm -rf xml html install-data-local: installfiles=`echo $(srcdir)/html/*`; \ if test "$$installfiles" = '$(srcdir)/html/*'; \ then echo '-- Nothing to install' ; \ else \ if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ $(mkinstalldirs) $${installdir} ; \ for i in $$installfiles; do \ echo '-- Installing '$$i ; \ $(INSTALL_DATA) $$i $${installdir}; \ done; \ if test -n "$(DOC_MODULE_VERSION)"; then \ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ mv -f $${installdir}/$(DOC_MODULE).devhelp \ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp; \ fi; \ ! which gtkdoc-rebase >/dev/null 2>&1 || \ gtkdoc-rebase --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir} ; \ fi uninstall-local: if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ rm -rf $${installdir} # # Require gtk-doc when making dist # if ENABLE_GTK_DOC dist-check-gtkdoc: else dist-check-gtkdoc: @echo "*** gtk-doc must be installed and enabled in order to make dist" @false endif dist-hook: dist-check-gtkdoc dist-hook-local mkdir $(distdir)/tmpl mkdir $(distdir)/xml mkdir $(distdir)/html -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl -cp $(srcdir)/xml/*.xml $(distdir)/xml cp $(srcdir)/html/* $(distdir)/html -cp $(srcdir)/$(DOC_MODULE).types $(distdir)/ -cp $(srcdir)/$(DOC_MODULE)-sections.txt $(distdir)/ cd $(distdir) && rm -f $(DISTCLEANFILES) ! which gtkdoc-rebase >/dev/null 2>&1 || \ gtkdoc-rebase --online --relative --html-dir=$(distdir)/html .PHONY : dist-hook-local docs libunicap/intltool-extract.in0000644000175000017500000000000013164711411017107 0ustar zmoelnigzmoelniglibunicap/intltool-merge.in0000644000175000017500000000000013164711411016534 0ustar zmoelnigzmoelniglibunicap/config.rpath0000755000175000017500000003744413164711411015601 0ustar zmoelnigzmoelnig#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2006 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file 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. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; darwin*) case $cc_basename in xlc*) wl='-Wl,' ;; esac ;; mingw* | pw32* | os2*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; newsos6) ;; linux*) case $cc_basename in icc* | ecc*) wl='-Wl,' ;; pgcc | pgf77 | pgf90) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; sco3.2v5*) ;; solaris*) wl='-Wl,' ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) wl='-Wl,' ;; sysv4*MP*) ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we cannot use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; interix3*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; bsdi[45]*) ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if test "$GCC" = yes ; then : else case $cc_basename in xlc*) ;; *) ld_shlibs=no ;; esac fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd1*) ld_shlibs=no ;; freebsd2.2*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; freebsd2*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | kfreebsd*-gnu | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; openbsd*) hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. libname_spec='lib$name' case "$host_os" in aix3*) ;; aix4* | aix5*) ;; amigaos*) ;; beos*) ;; bsdi[45]*) ;; cygwin* | mingw* | pw32*) shrext=.dll ;; darwin* | rhapsody*) shrext=.dylib ;; dgux*) ;; freebsd1*) ;; kfreebsd*-gnu) ;; freebsd* | dragonfly*) ;; gnu*) ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac ;; interix3*) ;; irix5* | irix6* | nonstopux*) case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux*) ;; knetbsd*-gnu) ;; netbsd*) ;; newsos6) ;; nto-qnx*) ;; openbsd*) ;; os2*) libname_spec='$name' shrext=.dll ;; osf3* | osf4* | osf5*) ;; solaris*) ;; sunos4*) ;; sysv4 | sysv4.3*) ;; sysv4*MP*) ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ;; uts4*) ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' < Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. libunicap/AUTHORS0000644000175000017500000000025213164711411014324 0ustar zmoelnigzmoelnigArne Caspari Translators: Niki Kovacs - French translation Yury Aliaev - Russian translation libunicap/libunicap.pc.in0000644000175000017500000000027013164711411016153 0ustar zmoelnigzmoelnigprefix=@prefix@ exec_prefix=@exec_prefix@ Name: libunicap Description: video capture library Version: @dist_version@ Libs: -L@libdir@ -lunicap @RT_LIBS@ Cflags: -I@includedir@/unicap libunicap/include/0000755000175000017500000000000013164711411014700 5ustar zmoelnigzmoelniglibunicap/include/unicap.h0000644000175000017500000005626713164711411016350 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004-2011 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UNICAP_H__ #define __UNICAP_H__ #ifdef __cplusplus #define UNICAP_BEGIN_DECLS extern "C" { #define UNICAP_END_DECLS } #else #define UNICAP_BEGIN_DECLS #define UNICAP_END_DECLS #endif #include #include #include #include #include #define UNICAP_MAX_DEVICES 128 /** * unicap_buffer_type_t: * @UNICAP_BUFFER_TYPE_USER: buffer is provided by the application * @UNICAP_BUFFER_TYPE_SYSTEM: buffer is provided by the driver or library */ typedef enum { UNICAP_BUFFER_TYPE_USER = 0, UNICAP_BUFFER_TYPE_SYSTEM, } unicap_buffer_type_t; typedef enum { UNICAP_FLAGS_BUFFER_TYPE_USER = 1, UNICAP_FLAGS_BUFFER_TYPE_SYSTEM = 1 << 1, UNICAP_FLAGS_BUFFER_INTERLACED = 1 << 2, UNICAP_FLAGS_BUFFER_ODD_FIELD_FIRST = 1 << 3, UNICAP_FLAGS_BUFFER_LOCKED = 1 << 16, } unicap_buffer_flags_t; typedef struct unicap_data_buffer_private unicap_data_buffer_private_t; /** * unicap_device_t: * @identifier: unique textual ID of a device * @model_name: model name of the device * @vendor_name: name of the device vendor * @model_id: unique model id, ie. serial number * @vendor_id: numerical ID of the vendor ( eg. USB Vendor ID ) * @cpi_layer: name of the plugin used to communicate with the device * @device: name of the device file, if any * @flags: flags * * A struct defining a device * */ struct _unicap_device_t { char identifier[128]; char model_name[128]; char vendor_name[128]; unsigned long long model_id; unsigned int vendor_id; char cpi_layer[1024]; char device[1024]; unsigned int flags; }; typedef struct _unicap_device_t unicap_device_t; /** * unicap_rect_t: * @x: horizontal position * @y: vertical position * @width: width of the rectangle * @height: height of the rectangle * * A struct defining a rectangle */ struct _unicap_rect_t { int x; int y; int width; int height; }; typedef struct _unicap_rect_t unicap_rect_t; /** * unicap_format_flags_t: * * Flags used in #unicap_format_t. * * The first five bits are used to specify the number of significant * bits in the pixel data. In order to access the number of sigificant * bits, do a bitwise AND operation with * @UNICAP_FLAGS_SIGNIFICANT_BITS_MASK. If all bits in the data are * significant, the special value @UNICAP_FLAGS_SIGNIFICANT_BITS_ALL * can be used. * * @UNICAP_FLAGS_SIGNIFICANT_BITS_ALL: all bits are significant * @UNICAP_FLAGS_SIGNIFICANT_BITS_MASK: mask to access the number of significant bits */ typedef enum { UNICAP_FLAGS_SIGNIFICANT_BITS_ALL = 0, UNICAP_FLAGS_SIGNIFICANT_BITS_MASK = 0x1F, UNICAP_FLAGS_FIELD_ALTERNATE = 1<<5, UNICAP_FLAGS_FIELD_TOP = 1<<6, UNICAP_FLAGS_FIELD_BOTTOM = 1<<7, UNICAP_FLAGS_FIELD_INTERLACED = 1<<8, } unicap_format_flags_t; /** * unicap_format_t: * @identifier: unique textual identifier of this format * @size: size of the format * @min_size: minimum size * @max_size: maximum size * @h_stepping: horizontal stepping * @v_stepping: vertical stepping * @sizes: array of allowed sizes. Might be NULL * @size_count: number of element in the sizes array * @bpp: bits per pixel * @fourcc: FOURCC describing the colour format * @flags: * @buffer_types: * @system_buffer_count: * @buffer_size: amount of memory required by one data buffer of this * format * @buffer_type: * */ struct _unicap_format_t { char identifier[128]; unicap_rect_t size; unicap_rect_t min_size; unicap_rect_t max_size; int h_stepping; int v_stepping; unicap_rect_t *sizes; int size_count; int bpp; unsigned int fourcc; unicap_format_flags_t flags; unsigned int buffer_types; int system_buffer_count; size_t buffer_size; unicap_buffer_type_t buffer_type; }; typedef struct _unicap_format_t unicap_format_t; /** * unicap_data_buffer_t: * @format: a #unicap_format_t describing the layout of the data * buffer * @frame_number: * @fill_time: the time when capturing completed on this buffer * @duration: frame duration of this buffer ( might not be present on * all devices ) * @capture_start_time: the time when the capturing started on this * buffer ( might not be supported on all devices ) * @data: the image data * @buffer_size: size of the memory buffer pointed to by data * @type: * */ struct _unicap_data_buffer_t { unicap_format_t format; int frame_number; struct timeval fill_time; struct timeval duration; struct timeval capture_start_time; unsigned char *data; size_t buffer_size; unicap_buffer_type_t type; unicap_buffer_flags_t flags; unicap_data_buffer_private_t *priv; }; typedef struct _unicap_data_buffer_t unicap_data_buffer_t; /** * unicap_property_range_t: * @min: minimum value * @max: maximum value */ struct _unicap_property_range_t { double min; double max; }; typedef struct _unicap_property_range_t unicap_property_range_t; /** * unicap_property_value_list_t: * @values: array of values * @value_count: number of elements in values array * */ struct _unicap_property_value_list_t { double *values; int value_count; }; typedef struct _unicap_property_value_list_t unicap_property_value_list_t; /** * unicap_property_menu_t: * @menu_items: an array of menu items * @menu_item_count: number of elements in the menu_items array * */ struct _unicap_property_menu_t { char **menu_items; int menu_item_count; }; typedef struct _unicap_property_menu_t unicap_property_menu_t; /** * unicap_property_type_enum_t: * @UNICAP_PROPERTY_TYPE_RANGE: a property with a value in a given * range * @UNICAP_PROPERTY_TYPE_VALUE_LIST: a property with a value out of a * list of values * @UNICAP_PROPERTY_TYPE_MENU: * @UNICAP_PROPERTY_TYPE_DATA: * @UNICAP_PROPERTY_TYPE_FLAGS: a property where only the flags are valid */ typedef enum { UNICAP_PROPERTY_TYPE_RANGE = 0, UNICAP_PROPERTY_TYPE_VALUE_LIST, UNICAP_PROPERTY_TYPE_MENU, UNICAP_PROPERTY_TYPE_DATA, UNICAP_PROPERTY_TYPE_FLAGS, UNICAP_PROPERTY_TYPE_UNKNOWN } unicap_property_type_enum_t; #ifndef UNICAP_FLAGS_NOT_AS_ENUM typedef enum { UNICAP_FLAGS_MANUAL = 1ULL, UNICAP_FLAGS_AUTO = (1ULL<<1ULL), UNICAP_FLAGS_ONE_PUSH = (1ULL<<2ULL), UNICAP_FLAGS_READ_OUT = (1ULL<<3ULL), UNICAP_FLAGS_ON_OFF = (1ULL<<4ULL), UNICAP_FLAGS_READ_ONLY = (1ULL<<5ULL), UNICAP_FLAGS_FORMAT_CHANGE = (1ULL<<6ULL), UNICAP_FLAGS_WRITE_ONLY = (1ULL<<7ULL), UNICAP_FLAGS_CHECK_STEPPING = (1ULL<<32ULL), UNICAP_FLAGS_DUMMY_VALUE = (0xffffffffffffffffULL) } unicap_property_flags_t; #else #define UNICAP_FLAGS_MANUAL (1ULL) #define UNICAP_FLAGS_AUTO (1ULL<<1ULL) #define UNICAP_FLAGS_ONE_PUSH (1ULL<<2ULL) #define UNICAP_FLAGS_READ_OUT (1ULL<<3ULL) #define UNICAP_FLAGS_ON_OFF (1ULL<<4ULL) #define UNICAP_FLAGS_READ_ONLY (1ULL<<5ULL) #define UNICAP_FLAGS_FORMAT_CHANGE (1ULL<<6ULL) #define UNICAP_FLAGS_WRITE_ONLY (1ULL<<7ULL) #define UNICAP_FLAGS_CHECK_STEPPING (1ULL<<32ULL) #define UNICAP_FLAGS_DUMMY_VALUE (0xffffffffffffffffULL) typedef u_int64_t unicap_property_flags_t; #endif /** * unicap_property_t: * @identifier: unique textual identifier of this properties * @category: a category for this property, for example: 'Lens Control' for zoom and focus properties * @unit: optional unit, for example: 's' for Exposure * denoting the Exposure time in seconds * @relations: properties that might their state or value when * changing this property * @relations_count: size of the relations array * @value: for UNICAP_PROPERTY_TYPE_RANGE and UNICAP_PROPERTY_TYPE_VALUE_LIST properties: current value * @menu_item: for UNICAP_PROPERTY_TYPE_MENU properties: selected menu entry * @range: for UNICAP_PROPERTY_TYPE_RANGE properties: valid range for value * @value_list: for UNICAP_PROPERTY_TYPE_VALUE_LIST properties: list * of valid values * @menu: for UNICAP_PROPERTY_TYPE_MENU properties: menu * @stepping: for UNICAP_PROPERTY_TYPE_RANGE properties: stepping * @type: the type of the property * @flags: when enumerated, this field contains the default flags for the property; for get/set operations, this * field contains the actual flags * @flags_mask: when enumerated, this field contains the allowed flags for the property; for get/set operations, this field acts as a mask * @property_data: a pointer to an opaque data structure * @property_data_size: size of the data structure pointed at by property_data */ struct _unicap_property_t { char identifier[128]; char category[128]; char unit[128]; char **relations; int relations_count; union { double value; char menu_item[128]; }; union{ unicap_property_range_t range; unicap_property_value_list_t value_list; unicap_property_menu_t menu; }; double stepping; unicap_property_type_enum_t type; unicap_property_flags_t flags; unicap_property_flags_t flags_mask; void *property_data; size_t property_data_size; }; typedef struct _unicap_property_t unicap_property_t; typedef enum { UNICAP_EVENT_FIRST = 0, UNICAP_EVENT_DEVICE_REMOVED = 0, UNICAP_EVENT_NEW_DEVICE, UNICAP_EVENT_NEW_FRAME, UNICAP_EVENT_DROP_FRAME, UNICAP_EVENT_FORMAT_CHANGED, UNICAP_EVENT_LAST } unicap_event_t; typedef struct _unicap_handle *unicap_handle_t; typedef void (*unicap_callback_t) (unicap_event_t event, ...); typedef void (*unicap_new_frame_callback_t) (unicap_event_t event, unicap_handle_t handle, unicap_data_buffer_t *buffer, void *user_ptr); typedef void (*unicap_drop_frame_callback_t) (unicap_event_t event, unicap_handle_t handle, void *user_ptr); typedef void (*unicap_new_device_callback_t) (unicap_event_t event, unicap_device_t *device, void *user_ptr); typedef void (*unicap_format_changed_callback_t) (unicap_event_t event, unicap_device_t *device, unicap_format_t *format, void *user_ptr); UNICAP_BEGIN_DECLS /** * unicap_check_version: * @major: major version to check against * @minor: minor version to check against * @micro: micro version to check against * * Checks that the unicap library version is compatible with given * version * * Returns: TRUE if compatible */ unicap_status_t unicap_check_version( unsigned int major, unsigned int minor, unsigned int micro ); /** * unicap_reenumerate_devices: * @count: if not NULL, receives number of devices found * * Rebuild internal list of devices. * * Returns: status */ unicap_status_t unicap_reenumerate_devices( int *count ); /** * unicap_enumerate_devices: * @specifier: specifies which devices should be returned, or NULL * @device: receives the device * @index: number of the device to be enumerated * * Enumerates currently connected video capture devices * * Returns: status */ unicap_status_t unicap_enumerate_devices( unicap_device_t *specifier, unicap_device_t *device, int index ); /** * unicap_open: * @handle: receives the new handle * @device: device to open, as returned by #unicap_enumerate_devices * * Acquire a handle to a device. * * Returns: status */ unicap_status_t unicap_open( unicap_handle_t *handle, unicap_device_t *device ); /** * unicap_register_callback: * @handle: a handle * @event: event to register a callback for * @callback: the callback function to call when the event occurs * @user_ptr: user provided data that gets passed to the callback function * */ unicap_status_t unicap_register_callback( unicap_handle_t handle, unicap_event_t event, unicap_callback_t callback, void *user_ptr ); /** * unicap_unregister_callback: * @handle: a handle * @event: the event to clear * * Returns: status */ unicap_status_t unicap_unregister_callback( unicap_handle_t handle, unicap_event_t event ); /** * unicap_close: * @handle: a handle * * Clsoing a handle decrements the reference count on the device. If * the reference count is 0, all resources associated with the device * get freed. * * Returns: status */ unicap_status_t unicap_close( unicap_handle_t handle ); /** * unicap_get_device: * @handle: a handle * @device: a pointer to the location where the device should be stored * * Gets the device controled by handle * * Returns: status */ unicap_status_t unicap_get_device( unicap_handle_t handle, unicap_device_t *device ); /** * unicap_clone_handle: * @handle: the handle to clone * * Copies the handle, increment the reference count * * Returns: new handle */ unicap_handle_t unicap_clone_handle( unicap_handle_t handle ); /** * unicap_reenumerate_formats: * @handle: A handle * @count: Receives the number of formats currently supported by the device. Might be NULL * * Re-create the list of formats supported by the device. Invalidates all data returned by prior calls * to unicap_emumerate_formats() and unicap_get_format(). * * Returns: status */ unicap_status_t unicap_reenumerate_formats( unicap_handle_t handle, int *count ); /** * unicap_enumerate_formats: * @handle: A handle * @specifier: limits the enumerated formats to the ones matching the fields in specifier. Fields set to -1 in the specifier are ignored * @format: A pointer to allocated storage where the enumerated format shoudl be stored * @index: index of the format in the enumeration * * Enumerate formats known to the device * * Returns: STATUS_NO_MORE_FORMATS: end of the list of matching formats has been reached */ unicap_status_t unicap_enumerate_formats( unicap_handle_t handle, unicap_format_t *specifier, unicap_format_t *format, int index ); /** * unicap_set_format: * @handle: a handle * @format: the format to set * * Set a format. * * Returns: STATUS_NO_MATCH: given format not valid for device */ unicap_status_t unicap_set_format( unicap_handle_t handle, unicap_format_t *format ); /** * unicap_get_format: * @handle: a handle * @format: a pointer to the location where the returned format should be stored * * Get the current format * * Returns: status */ unicap_status_t unicap_get_format( unicap_handle_t handle, unicap_format_t *format ); /** * unicap_reenumerate_properties: * @handle: a handle * @count: receives number of properties supported by the device. Might be NULL * * Re-create the list of properties supported by the device. This invalidates all data returned by prior calls to * unicap_enumerate_properties() and unicap_get_property() * * Returns: status */ unicap_status_t unicap_reenumerate_properties( unicap_handle_t handle, int *count ); /** * unicap_enumerate_properties: * @handle: a handle * @specifier: specifier * @property: a pointer to the location where the enumerated property should be stored * @index: index of the property * * Enumerate properties matching "specifier" * * Returns: status */ unicap_status_t unicap_enumerate_properties( unicap_handle_t handle, unicap_property_t *specifier, unicap_property_t *property, int index ); /** * unicap_set_property: * @handle: a handle * @property: the property to set * * Set a device property * * Returns: status */ unicap_status_t unicap_set_property( unicap_handle_t handle, unicap_property_t *property ); /** * unicap_set_property_value: Sets the value of a property * @handle: A handle * @identifier: identifier of the property to set * @value: new value * * Set a RANGE or VALUE_LIST property * * Returns: status */ unicap_status_t unicap_set_property_value( unicap_handle_t handle, char *identifier, double value ); /** * unicap_set_property_manual: * @handle: A handle * @identifier: identifier of the property to set * * Sets a property to manual mode, disabling the automatic mode * * Returns: status */ unicap_status_t unicap_set_property_manual( unicap_handle_t handle, char *identifier ); /** * unicap_set_property_auto: * @handle: A handle * @identifier: identifier of the property to set * * Sets the property to automatic mode * * Returns: status */ unicap_status_t unicap_set_property_auto( unicap_handle_t handle, char *identifier ); /** * unicap_set_property_one_push: * @handle: a handle * @identifier: identifier of the property to set * * Enable one push mode on a property * * Returns: status */ unicap_status_t unicap_set_property_one_push( unicap_handle_t handle, char *identifier ); /** * unicap_get_property: * @handle: a handle * @property: a pointer to the location where the returned property should be stored * * Get a device property * * Returns: status */ unicap_status_t unicap_get_property( unicap_handle_t handle, unicap_property_t *property ); /** * unicap_get_property_value: * @handle: a handle * @identifier: identifier of the property to query * @value: a pointer to the location where the value should be stored * * Returns the value of a property * * Returns: status */ unicap_status_t unicap_get_property_value( unicap_handle_t handle, const char *identifier, double *value ); /** * unicap_get_property_menu: * @handle: A handle * @identifier: identifier of the property to query * @value: pointer to store the string location * * Returns the menu string of a property. Property must be of * UNICAP_PROPERTY_TYPE_MENU type. The returned string is owned by the * unicap library and might be overwritten by subsequent calls to unicap_get_property_menu. * * Returns: status */ unicap_status_t unicap_get_property_menu( unicap_handle_t handle, const char *identifier, char **value ); /** * unicap_get_property_auto: * @handle: a handle * @identifier: identifier of the property to query * @enabled: location to store the enabled flag * * Retrieve the current property auto mode * * Returns: status */ unicap_status_t unicap_get_property_auto( unicap_handle_t handle, const char *identifier, int *enabled ); /** * unicap_start_capture: * @handle: a handle * * Start the capture device. After this call, unicap_wait_buffer calls are allowed * * Returns: status */ unicap_status_t unicap_start_capture( unicap_handle_t handle ); /** * unicap_stop_capture: * @handle: A handle * * Stop the capture device * * Returns: status */ unicap_status_t unicap_stop_capture( unicap_handle_t handle ); /** * unicap_queue_buffer: * @handle: A handle * @data_buffer: A pointer to the buffer to queue * * Queue a buffer to be filled by the capture device. The queued * buffer must not be touched ( especially not be freed ) until it is * in the ready queue or dequeued. Supplied buffer must be at least of * the buffer size returned by get_format * * Returns: status */ unicap_status_t unicap_queue_buffer( unicap_handle_t handle, unicap_data_buffer_t *data_buffer ); /** * unicap_dequeue_buffer: * @handle: A handle * @data_buffer: receives the dequeued buffer or NULL if no buffer was queued * * Removes the first buffer from the queue. Depending on the * device:Can only be called if the capture device is stopped. * * Returns: status */ unicap_status_t unicap_dequeue_buffer( unicap_handle_t handle, unicap_data_buffer_t **data_buffer ); /** * unicap_wait_buffer: * @handle: A handle * @data_buffer: A pointer to the location where the returned buffer should be stored * * Removes a buffer from the ready queue. If no buffer is available, this function blocks until a buffer got filled. * * Returns: status */ unicap_status_t unicap_wait_buffer( unicap_handle_t handle, unicap_data_buffer_t **data_buffer ); /** * unicap_poll_buffer: * @handle: A handle * @count: A pointer to the location where return value should be stored * * Poll for buffers in the fill queue * * Returns: status */ unicap_status_t unicap_poll_buffer( unicap_handle_t handle, int *count ); unicap_status_t unicap_describe_device( unicap_device_t *device, char *buffer, size_t *buffer_size ); unicap_status_t unicap_describe_format( unicap_format_t *format, char *buffer, size_t *buffer_size ); unicap_status_t unicap_describe_property( unicap_property_t *property, char *buffer, size_t *buffer_size ); unicap_status_t unicap_void_device( unicap_device_t *device ); unicap_status_t unicap_void_format( unicap_format_t *format ); unicap_status_t unicap_void_property( unicap_property_t *property ); unicap_format_t *unicap_copy_format( unicap_format_t *dest, const unicap_format_t *src ); unicap_property_t *unicap_copy_property( unicap_property_t *dest, const unicap_property_t *src ); #ifdef UNICAP_FLAGS_NOT_AS_ENUM #define UNICAP_FLAGS_LOCKED ( 1<<0 ) #define UNICAP_FLAGS_LOCK_CURRENT_PROCESS ( 1<<1 ) #else typedef enum { UNICAP_FLAGS_LOCKED = ( 1<< 0 ), UNICAP_FLAGS_LOCK_CURRENT_PROCESS = ( 1<< 1 ), } unicap_lock_flags_t; #endif /** * unicap_lock_stream: * @handle: * */ unicap_status_t unicap_lock_stream( unicap_handle_t handle ); /** * unicap_lock_stream: * @handle: * */ unicap_status_t unicap_unlock_stream( unicap_handle_t handle ); /** * unicap_is_stream_locked: * @device: * * */ int unicap_is_stream_locked( unicap_device_t *device ); unicap_status_t unicap_lock_properties( unicap_handle_t handle ); unicap_status_t unicap_unlock_properties( unicap_handle_t handle ); void unicap_cpi_register_event_notification( void *, void *data, unicap_handle_t handle ); /* */ void unicap_cache_init( void ); int unicap_get_ref_count( unicap_handle_t handle ); typedef void (*unicap_data_buffer_func_t)( unicap_data_buffer_t *buffer, void *ptr ); struct unicap_data_buffer_init_data { unicap_data_buffer_func_t free_func; void *free_func_data; unicap_data_buffer_func_t ref_func; void *ref_func_data; unicap_data_buffer_func_t unref_func; void *unref_func_data; }; typedef struct unicap_data_buffer_init_data unicap_data_buffer_init_data_t; unicap_data_buffer_t *unicap_data_buffer_new( unicap_format_t *format ); void unicap_data_buffer_init( unicap_data_buffer_t *buffer, unicap_format_t *format, unicap_data_buffer_init_data_t *init_data ); void unicap_data_buffer_free( unicap_data_buffer_t *buffer ); unicap_status_t unicap_data_buffer_ref( unicap_data_buffer_t *buffer ); unicap_status_t unicap_data_buffer_unref( unicap_data_buffer_t *buffer ); unsigned int unicap_data_buffer_get_refcount( unicap_data_buffer_t *buffer ); void *unicap_data_buffer_set_user_data( unicap_data_buffer_t *buffer, void *data ); void *unicap_data_buffer_get_user_data( unicap_data_buffer_t *buffer ); UNICAP_END_DECLS #endif//__UNICAP_H__ libunicap/include/Makefile.am0000644000175000017500000000027613164711411016741 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in # headers to be installed pkgincludedir=$(includedir)/unicap pkginclude_HEADERS = unicap.h unicap_status.h unicap_version.h debug.h EXTRA_DIST = debug.h libunicap/include/check_match.h0000644000175000017500000000212413164711411017301 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CHECK_MATCH_H__ #define __CHECK_MATCH_H__ #include "unicap.h" int _check_device_match( unicap_device_t *specifier, unicap_device_t *device ); int _check_format_match( unicap_format_t *specifier, unicap_format_t *format ); int _check_property_match( unicap_property_t *specifier, unicap_property_t *property ); #endif libunicap/include/debug.h0000644000175000017500000000250013164711411016134 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DEBUG_H__ #define __DEBUG_H__ // define DEBUG if you want debug output #ifdef DEBUG #include #define TRACE( x... ) {printf( "%s %s (%d) :", __FILE__, __FUNCTION__, __LINE__ ); printf( x );} #define ASSERT( x ) {if(!x) { printf( "assertion failed: %s %s (%d)", __FILE__, __FUNCTION__, __LINE__ ); abort)_;} } #define DBGOUT( x... ) {printf(x);} #else #define TRACE( x... ) #define ASSERT( x ) #define DBGOUT( x... ) #endif #define ERROR( x... ) fprintf( stderr, "% %s (%d) :", __FILE__, __FUNCTION__, __LINE__ ); printf( x ) #endif//__DEBUG_H__ libunicap/include/unicap_private.h0000644000175000017500000000426613164711411020072 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UNICAP_PRIVATE_H__ #define __UNICAP_PRIVATE_H__ #include #include #include #include #include #include #define SHM_REG_VERSION 1 #define DLLEXPORT __declspec(dllexport) struct _unicap_callback_info { unicap_callback_t func; void *user_ptr; } unicap_callback_info; struct _unicap_shm_reg { int shm_reg_version; char device_identifier[128]; int use_count; pid_t stream_owner; pid_t properties_owner; } unicap_shm_reg; struct unicap_device_lock { int have_stream_lock; int temporary_stream_lock; int have_ppty_lock; int stream_lock_fd; int ppty_lock_fd; int stream_sem_id; int property_sem_id; }; struct _unicap_handle { unicap_device_t device; struct _unicap_cpi cpi; void *dlhandle; void *cpi_data; unsigned int cpi_flags; key_t sem_key; int sem_id; int *ref_count; struct unicap_device_lock *lock; struct _unicap_callback_info *cb_info; } unicap_handle; struct unicap_data_buffer_private { unsigned int ref_count; unicap_data_buffer_func_t free_func; void *free_func_data; unicap_data_buffer_func_t ref_func; void *ref_func_data; unicap_data_buffer_func_t unref_func; void *unref_func_data; void *user_data; sem_t lock; }; unicap_status_t unicap_real_enumerate_devices( int *count ); #endif //__UNICAP_PRIVATE_H__ libunicap/include/unicap_helpers.h0000644000175000017500000000170313164711411020053 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UNICAP_HELPERS_H__ #define __UNICAP_HELPERS_H__ #include unicap_property_t *unicap_copy_property_nodata( unicap_property_t *dest, unicap_property_t *src ); #endif libunicap/include/unicap_version.h.in0000644000175000017500000000060713164711411020505 0ustar zmoelnigzmoelnig#ifndef __UNICAP_VERSION_H__ #define __UNICAP_VERSION_H__ #define UNICAP_MAJOR_VERSION @unicap_major_version@ #define UNICAP_MINOR_VERSION @unicap_minor_version@ #define UNICAP_MICRO_VERSION @unicap_micro_version@ extern const unsigned int unicap_major_version; extern const unsigned int unicap_minor_version; extern const unsigned int unicap_micro_version; #endif//__UNICAP_VERSION_H__ libunicap/include/unicap_status.h0000644000175000017500000000727713164711411017750 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __STATUS_H__ #define __STATUS_H__ #define STATUS_SUCCESS 0x00000000 #define STATUS_INTERNAL 0x10000000 #define STATUS_WARNING 0x40000000 #define STATUS_FAILURE 0x80000000 #define STATUS_NO_DEVICE ( STATUS_FAILURE | 0x1 ) #define STATUS_CHANNEL_ALREADY_FREE ( STATUS_FAILURE | 0x2 ) #define STATUS_INSUFFICIENT_BANDWIDTH ( STATUS_FAILURE | 0x3 ) #define STATUS_INVALID_PARAMETER ( STATUS_FAILURE | 0x4 ) #define STATUS_IS_RECEIVING ( STATUS_FAILURE | 0x5 ) #define STATUS_IS_STOPPED ( STATUS_FAILURE | 0x6 ) #define STATUS_NO_VIDEO_MODE ( STATUS_FAILURE | 0x7 ) #define STATUS_NO_CHANNEL ( STATUS_FAILURE | 0x8 ) #define STATUS_TIMEOUT ( STATUS_FAILURE | 0x9 ) #define STATUS_NO_BUFFERS ( STATUS_FAILURE | 0xa ) #define STATUS_CPI_OPEN_FAILED ( STATUS_FAILURE | 0xb ) #define STATUS_NO_MEM ( STATUS_FAILURE | 0xc ) #define STATUS_INVALID_CPI ( STATUS_FAILURE | 0xd ) #define STATUS_UNSUPPORTED_CPI_VERSION ( STATUS_FAILURE | 0xe ) #define STATUS_INVALID_HANDLE ( STATUS_FAILURE | 0xf ) #define STATUS_NOT_IMPLEMENTED ( STATUS_FAILURE | 0x1c ) #define STATUS_NO_MATCH ( STATUS_FAILURE | 0x1e ) #define STATUS_NO_FORMAT ( STATUS_FAILURE | 0x1f ) #define STATUS_PROPERTY_WRONG_STEPPING ( STATUS_FAILURE | 0x20 ) #define STATUS_PROPERTY_VALUE_NOT_IN_LIST ( STATUS_FAILURE | 0x21 ) #define STATUS_BUFFER_TOO_SMALL ( STATUS_FAILURE | 0x22 ) #define STATUS_UNSUPPORTED_BUFFER_TYPE ( STATUS_FAILURE | 0x23 ) #define STATUS_INSUFFICIENT_RESOURCES ( STATUS_FAILURE | 0x25 ) #define STATUS_FRAME_RATE_NOT_AVAILABLE ( STATUS_FAILURE | 0x26 ) #define STATUS_PERMISSION_DENIED ( STATUS_FAILURE | 0x27 ) #define STATUS_FILE_NOT_FOUND ( STATUS_FAILURE | 0x28 ) #define STATUS_UNSUPPORTED_CODEC ( STATUS_FAILURE | 0x101 ) #define STATUS_RAW1394_NO_KERNEL_SUPPORT ( STATUS_FAILURE | 0x80 ) #define STATUS_RAW1394_NO_CARDS ( STATUS_FAILURE | 0x81 ) #define STATUS_INCOMPATIBLE_MAJOR_VERSION ( STATUS_FAILURE | 0xf00 ) #define STATUS_INCOMPATIBLE_MINOR_VERSION ( STATUS_FAILURE | 0xf01 ) #define STATUS_INCOMPATIBLE_MICRO_VERSION ( STATUS_FAILURE | 0xf02 ) #define STATUS_CAPTURE_ALREADY_STARTED ( STATUS_WARNING | 0x1 ) #define STATUS_CAPTURE_ALREADY_STOPPED ( STATUS_WARNING | 0x2 ) #define STATUS_WARN_DEVICE_QUERY_FAIL ( STATUS_WARNING | 0x3 ) #define STATUS_SKIP_CTRL ( STATUS_INTERNAL | 0x1 ) #define SUCCESS( x ) ( ( (x) & 0xff000000 ) == 0x0 ) typedef int unicap_status_t; #endif //__STATUS_H__ libunicap/data/0000755000175000017500000000000013164711411014166 5ustar zmoelnigzmoelniglibunicap/data/Makefile.am0000644000175000017500000000014113164711411016216 0ustar zmoelnigzmoelnigeuvccamrulesdir=/etc/udev/rules.d euvccamrules_DATA=50-euvccam.rules EXTRA_DIST=50-euvccam.ruleslibunicap/data/50-euvccam.rules0000644000175000017500000000104213164711411017104 0ustar zmoelnigzmoelnigATTRS{idVendor}=="199e", ATTRS{idProduct}=="8201", GROUP="video", MODE="0660" ATTRS{idVendor}=="199e", ATTRS{idProduct}=="8202", GROUP="video", MODE="0660" ATTRS{idVendor}=="199e", ATTRS{idProduct}=="8203", GROUP="video", MODE="0660" ATTRS{idVendor}=="199e", ATTRS{idProduct}=="8204", GROUP="video", MODE="0660" ATTRS{idVendor}=="199e", ATTRS{idProduct}=="8205", GROUP="video", MODE="0660" ATTRS{idVendor}=="199e", ATTRS{idProduct}=="8206", GROUP="video", MODE="0660" ATTRS{idVendor}=="199e", ATTRS{idProduct}=="8207", GROUP="video", MODE="0660" libunicap/po/0000755000175000017500000000000013164711411013673 5ustar zmoelnigzmoelniglibunicap/po/POTFILES.in0000644000175000017500000000044713164711411015455 0ustar zmoelnigzmoelnig# List of source files which contain translatable strings. libucil/ucil_theora.c libunicapgtk/unicapgtk_device_property.c libunicapgtk/unicapgtk_property_dialog.c cpi/v4l2cpi/v4l2.c cpi/v4l2cpi/v4l2_i18n_strings.h cpi/v4l2cpi/tiseuvccam.c cpi/v4l2cpi/tisuvccam.c cpi/dcam/dcam_property_table.h libunicap/po/de.po0000644000175000017500000001451513164711411014631 0ustar zmoelnigzmoelnig# translation of unicap. # Copyright (C) 2007 Arne Caspari # This file is distributed under the same license as the unicap package. # Arne Caspari, 2007. # # msgid "" msgstr "" "Project-Id-Version: unicap VERSION\n" "Report-Msgid-Bugs-To: arne@unicap-imaging.org\n" "POT-Creation-Date: 2007-09-06 18:12+0200\n" "PO-Revision-Date: 2007-09-06 18:15+0200\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=\n" "Content-Transfer-Encoding: " #: ../libunicapgtk/unicapgtk_device_property.c:654 msgid "Auto" msgstr "Auto" #: ../libunicapgtk/unicapgtk_device_property.c:667 msgid "One Push" msgstr "Einmalig" #: ../cpi/v4l2/v4l2.c:55 ../cpi/v4l2/v4l2_i18n_strings.h:35 msgid "video source" msgstr "Videoquelle" #: ../cpi/v4l2/v4l2.c:56 msgid "video norm" msgstr "Videonorm" #: ../cpi/v4l2/v4l2.c:57 ../cpi/v4l2/v4l2_i18n_strings.h:22 #: ../cpi/dcam/dcam_property_table.h:887 msgid "frame rate" msgstr "Bildrate" #: ../cpi/v4l2/v4l2.c:131 msgid "STK-1135 USB2 Camera Controller" msgstr "STK-1135 USB2 Camera Controller" #: ../cpi/v4l2/v4l2.c:132 msgid "UVC Camera (eb1a:2761)" msgstr "UVC Camera" #: ../cpi/v4l2/v4l2.c:1040 msgid "video" msgstr "Video" #: ../cpi/v4l2/v4l2.c:1080 msgid "extended" msgstr "Erweitert" #: ../cpi/v4l2/v4l2_i18n_strings.h:14 msgid "anti-flicking" msgstr "Entflackern" #: ../cpi/v4l2/v4l2_i18n_strings.h:15 msgid "auto exposure/gain" msgstr "Automatische Belichtung/Verstärkung" #: ../cpi/v4l2/v4l2_i18n_strings.h:16 msgid "auto white balance" msgstr "Automaticher Weissabgleich" #: ../cpi/v4l2/v4l2_i18n_strings.h:17 msgid "Brightness" msgstr "Helligkeit" #: ../cpi/v4l2/v4l2_i18n_strings.h:18 ../cpi/dcam/dcam_property_table.h:186 msgid "brightness" msgstr "Helligkeit" #: ../cpi/v4l2/v4l2_i18n_strings.h:19 msgid "Contrast" msgstr "Kontrast" #: ../cpi/v4l2/v4l2_i18n_strings.h:20 msgid "contrast" msgstr "Kontrast" #: ../cpi/v4l2/v4l2_i18n_strings.h:21 msgid "Exposure, Auto" msgstr "Belichtung ( Auto )" #: ../cpi/v4l2/v4l2_i18n_strings.h:23 msgid "Gamma" msgstr "Gamma" #: ../cpi/v4l2/v4l2_i18n_strings.h:24 ../cpi/dcam/dcam_property_table.h:564 msgid "gamma" msgstr "Gamma" #: ../cpi/v4l2/v4l2_i18n_strings.h:25 msgid "horizontal flip" msgstr "horizontal Spiegeln" #: ../cpi/v4l2/v4l2_i18n_strings.h:26 msgid "Hue" msgstr "Farbton" #: ../cpi/v4l2/v4l2_i18n_strings.h:27 ../cpi/dcam/dcam_property_table.h:510 msgid "hue" msgstr "Farbton" #: ../cpi/v4l2/v4l2_i18n_strings.h:28 msgid "Power Line Frequency" msgstr "Stromnetzfrequenz" #: ../cpi/v4l2/v4l2_i18n_strings.h:29 msgid "resolution" msgstr "Auflösung" #: ../cpi/v4l2/v4l2_i18n_strings.h:30 msgid "Saturation" msgstr "Sättigung" #: ../cpi/v4l2/v4l2_i18n_strings.h:31 ../cpi/dcam/dcam_property_table.h:537 msgid "saturation" msgstr "Sättigung" #: ../cpi/v4l2/v4l2_i18n_strings.h:32 msgid "Sharpness" msgstr "Schärfe" #: ../cpi/v4l2/v4l2_i18n_strings.h:33 ../cpi/dcam/dcam_property_table.h:402 msgid "sharpness" msgstr "Schärfe" #: ../cpi/v4l2/v4l2_i18n_strings.h:34 msgid "vertical flip" msgstr "vertikal Spiegeln" #: ../cpi/v4l2/v4l2_i18n_strings.h:36 msgid "White Balance Temperature, Auto" msgstr "Weissabgleich Temperatur ( Auto )" #: ../cpi/v4l2/v4l2_i18n_strings.h:37 msgid "White Balance Temperature" msgstr "Farbtemperatur" #: ../cpi/v4l2/v4l2_i18n_strings.h:39 msgid "YUV 4:2:2 (YUYV)" msgstr "YUV 4:2:2 (YUYV)" #: ../cpi/v4l2/v4l2_i18n_strings.h:40 msgid "Uncompressed" msgstr "Unkomprimiert" #: ../cpi/dcam/dcam_property_table.h:33 msgid "Video" msgstr "Video" #: ../cpi/dcam/dcam_property_table.h:34 msgid "Exposure" msgstr "Belichtung" #: ../cpi/dcam/dcam_property_table.h:35 msgid "Lens Control" msgstr "Objektivsteuerung" #: ../cpi/dcam/dcam_property_table.h:36 msgid "Color" msgstr "Farbe" #: ../cpi/dcam/dcam_property_table.h:37 msgid "Device" msgstr "Gerät" #: ../cpi/dcam/dcam_property_table.h:43 msgid "constant low" msgstr "Dauerhaft aus" #: ../cpi/dcam/dcam_property_table.h:44 msgid "constant high" msgstr "Dauerhaft an" #: ../cpi/dcam/dcam_property_table.h:45 msgid "fixed duration" msgstr "Feste Dauer" #: ../cpi/dcam/dcam_property_table.h:46 msgid "exposure" msgstr "Belichtung" #: ../cpi/dcam/dcam_property_table.h:51 msgid "active low" msgstr "Low-Aktiv" #: ../cpi/dcam/dcam_property_table.h:52 msgid "active high" msgstr "High-Aktiv" #: ../cpi/dcam/dcam_property_table.h:141 msgid "free running" msgstr "Freilaufend" #: ../cpi/dcam/dcam_property_table.h:142 msgid "mode 0" msgstr "Modus 0" #: ../cpi/dcam/dcam_property_table.h:267 msgid "strobe_mode" msgstr "Strobemodus" #: ../cpi/dcam/dcam_property_table.h:293 msgid "strobe_duration" msgstr "Strobedauer" #: ../cpi/dcam/dcam_property_table.h:320 msgid "strobe_delay" msgstr "Strobeverzögerung" #: ../cpi/dcam/dcam_property_table.h:347 msgid "strobe_polarity" msgstr "Strobe Polarität" #: ../cpi/dcam/dcam_property_table.h:375 msgid "auto_exposure" msgstr "Automatische Belichtung/Verstärkung" #: ../cpi/dcam/dcam_property_table.h:429 msgid "white_balance_mode" msgstr "Automaticher Weissabgleich ( Modus )" #: ../cpi/dcam/dcam_property_table.h:456 msgid "white_balance_u" msgstr "Weissabgleich U" #: ../cpi/dcam/dcam_property_table.h:483 msgid "white_balance_v" msgstr "Weissabgleich V" #: ../cpi/dcam/dcam_property_table.h:591 msgid "shutter" msgstr "Belichtung" #: ../cpi/dcam/dcam_property_table.h:619 msgid "gain" msgstr "Verstärkung" #: ../cpi/dcam/dcam_property_table.h:646 msgid "iris" msgstr "Blende" #: ../cpi/dcam/dcam_property_table.h:673 msgid "focus" msgstr "Fokus" #: ../cpi/dcam/dcam_property_table.h:700 msgid "temperature" msgstr "Temperatur" #: ../cpi/dcam/dcam_property_table.h:727 msgid "trigger_mode" msgstr "Triggermodus" #: ../cpi/dcam/dcam_property_table.h:750 msgid "zoom" msgstr "Zoom" #. TRANSLATORS: Lens pan #: ../cpi/dcam/dcam_property_table.h:778 msgid "pan" msgstr "" #. TRANSLATORS: Lens tilt #: ../cpi/dcam/dcam_property_table.h:806 msgid "tilt" msgstr " " #: ../cpi/dcam/dcam_property_table.h:833 msgid "optical_filter" msgstr "Optischer Filter" #: ../cpi/dcam/dcam_property_table.h:860 msgid "capture_quality" msgstr "Aufnahmequalität" #. TRANSLATORS: Camera #. hardware register #: ../cpi/dcam/dcam_property_table.h:916 msgid "register" msgstr "Register" #: ../cpi/dcam/dcam_property_table.h:943 msgid "timeout" msgstr "Zeitüberschreitung" #: ../cpi/dcam/dcam_property_table.h:969 msgid "gpio" msgstr "Ein/Ausgänge" libunicap/po/ChangeLog0000644000175000017500000000141313164711411015444 0ustar zmoelnigzmoelnig2009-10-07 Arne Caspari * fr.po: fix: correct charset 2008-07-23 Arne Caspari * ru.po: Updates from Yurz Aliaev 2008-04-23 Arne Caspari * de.po: fixed some typos * fr.po: French translation from kiki novak 2007-08-30 gettextize * Makefile.in.in: New file, from gettext-0.16.1. * Rules-quot: New file, from gettext-0.16.1. * boldquot.sed: New file, from gettext-0.16.1. * en@boldquot.header: New file, from gettext-0.16.1. * en@quot.header: New file, from gettext-0.16.1. * insert-header.sin: New file, from gettext-0.16.1. * quot.sed: New file, from gettext-0.16.1. * remove-potcdate.sin: New file, from gettext-0.16.1. * POTFILES.in: New file. libunicap/po/fr.po0000644000175000017500000001416013164711411014644 0ustar zmoelnigzmoelnigmsgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: 2009-10-07 18:29+0200\n" "Last-Translator: Niki Kovacs \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../libunicapgtk/unicapgtk_device_property.c:654 msgid "Auto" msgstr "Auto" #: ../libunicapgtk/unicapgtk_device_property.c:667 msgid "One Push" msgstr "Unique" #: ../cpi/v4l2/v4l2.c:55 #: ../cpi/v4l2/v4l2_i18n_strings.h:35 msgid "video source" msgstr "Source vidéo" #: ../cpi/v4l2/v4l2.c:56 msgid "video norm" msgstr "Norme vidéo" #: ../cpi/v4l2/v4l2.c:57 #: ../cpi/v4l2/v4l2_i18n_strings.h:22 #: ../cpi/dcam/dcam_property_table.h:887 msgid "frame rate" msgstr "Taux d'images" #: ../cpi/v4l2/v4l2.c:131 msgid "STK-1135 USB2 Camera Controller" msgstr "Contrôleur caméra STK-1135 USB2" #: ../cpi/v4l2/v4l2.c:132 msgid "UVC Camera (eb1a:2761)" msgstr "Caméra UVC" #: ../cpi/v4l2/v4l2.c:1040 msgid "video" msgstr "Vidéo" #: ../cpi/v4l2/v4l2.c:1080 msgid "extended" msgstr "Etendu" #: ../cpi/v4l2/v4l2_i18n_strings.h:14 msgid "anti-flicking" msgstr "Anti-vacillement" #: ../cpi/v4l2/v4l2_i18n_strings.h:15 msgid "auto exposure/gain" msgstr "Exposition/Amplification automatique" #: ../cpi/v4l2/v4l2_i18n_strings.h:16 msgid "auto white balance" msgstr "Balance automatique" #: ../cpi/v4l2/v4l2_i18n_strings.h:17 msgid "Brightness" msgstr "Luminosité" #: ../cpi/v4l2/v4l2_i18n_strings.h:18 #: ../cpi/dcam/dcam_property_table.h:186 msgid "brightness" msgstr "Luminosité" #: ../cpi/v4l2/v4l2_i18n_strings.h:19 msgid "Contrast" msgstr "Contraste" #: ../cpi/v4l2/v4l2_i18n_strings.h:20 msgid "contrast" msgstr "Contraste" #: ../cpi/v4l2/v4l2_i18n_strings.h:21 msgid "Exposure, Auto" msgstr "Exposition ( Auto )" #: ../cpi/v4l2/v4l2_i8n_strings.h:23 msgid "Gamma" msgstr "Gamma" #: ../cpi/v4l2/v4l2_i18n_strings.h:24 #: ../cpi/dcam/dcam_property_table.h:564 msgid "gamma" msgstr "Gamma" #: ../cpi/v4l2/v4l2_i18n_strings.h:25 msgid "horizontal flip" msgstr "Miroir horizontal" #: ../cpi/v4l2/v4l2_i18n_strings.h:26 msgid "Hue" msgstr "Coloration" #: ../cpi/v4l2/v4l2_i18n_strings.h:27 #: ../cpi/dcam/dcam_property_table.h:510 msgid "hue" msgstr "Coloration" #: ../cpi/v4l2/v4l2_i18n_strings.h:28 msgid "Power Line Frequency" msgstr "Fréquence d'alimentation" #: ../cpi/v4l2/v4l2_i18n_strings.h:29 msgid "resolution" msgstr "Résolution" #: ../cpi/v4l2/v4l2_i18n_strings.h:30 msgid "Saturation" msgstr "Saturation" #: ../cpi/v4l2/v4l2_i18n_strings.h:31 #: ../cpi/dcam/dcam_property_table.h:537 msgid "saturation" msgstr "Saturation" #: ../cpi/v4l2/v4l2_i18n_strings.h:32 msgid "Sharpness" msgstr "Netteté" #: ../cpi/v4l2/v4l2_i18n_strings.h:33 #: ../cpi/dcam/dcam_property_table.h:402 msgid "sharpness" msgstr "Netteté" #: ../cpi/v4l2/v4l2_i18n_strings.h:34 msgid "vertical flip" msgstr "Miroir vertical" #: ../cpi/v4l2/v4l2_i18n_strings.h:36 msgid "White Balance Temperature, Auto" msgstr "Balance température ( Auto )" #: ../cpi/v4l2/v4l2_i18n_strings.h:37 msgid "White Balance Temperature" msgstr "Température couleur" #: ../cpi/v4l2/v4l2_i18n_strings.h:39 msgid "YUV 4:2:2 (YUYV)" msgstr "YUV 4:2:2 (YUYV)" #: ../cpi/v4l2/v4l2_i18n_strings.h:40 msgid "Uncompressed" msgstr "Décompressé" #: ../cpi/dcam/dcam_property_table.h:33 msgid "Video" msgstr "Vidéo" #: ../cpi/dcam/dcam_property_table.h:34 msgid "Exposure" msgstr "Exposition" #: ../cpi/dcam/dcam_property_table.h:35 msgid "Lens Control" msgstr "Contrôle de l'objectif" #: ../cpi/dcam/dcam_property_table.h:36 msgid "Color" msgstr "Couleur" #: ../cpi/dcam/dcam_property_table.h:37 msgid "Device" msgstr "Périphérique" #: ../cpi/dcam/dcam_property_table.h:43 msgid "constant low" msgstr "Désactivation constante" #: ../cpi/dcam/dcam_property_table.h:44 msgid "constant high" msgstr "Activation constante" #: ../cpi/dcam/dcam_property_table.h:46 msgid "exposure" msgstr "Exposition" #: ../cpi/dcam/dcam_property_table.h:51 msgid "active low" msgstr "Minimum actif" #: ../cpi/dcam/dcam_property_table.h:52 msgid "active high" msgstr "Maximum actif" #: ../cpi/dcam/dcam_property_table.h:141 msgid "free running" msgstr "Libre" #: ../cpi/dcam/dcam_property_table.h:142 msgid "mode 0" msgstr "Mode 0" #: ../cpi/dcam/dcam_property_table.h:267 msgid "strobe_mode" msgstr "Mode stroboscopique" #: ../cpi/dcam/dcam_property_table.h:293 msgid "strobe_duration" msgstr "Durée stroboscopique" #: ../cpi/dcam/dcam_property_table.h:320 msgid "strobe_delay" msgstr "Délai stroboscopique" #: ../cpi/dcam/dcam_property_table.h:347 msgid "strobe_polarity" msgstr "Polarité stroboscopique" #: ../cpi/dcam/dcam_property_table.h:375 msgid "auto_exposure" msgstr "Exposition/Amplification automatique" #: ../cpi/dcam/dcam_property_table.h:429 msgid "white_balance_mode" msgstr "Mode Balance Automatique" #: ../cpi/dcam/dcam_property_table.h:456 msgid "white_balance_u" msgstr "Balance U" #: ../cpi/dcam/dcam_property_table.h:483 msgid "white_balance_v" msgstr "Balance V" #: ../cpi/dcam/dcam_property_table.h:591 msgid "shutter" msgstr "Exposition" #: ../cpi/dcam/dcam_property_table.h:619 msgid "gain" msgstr "Gain" #: ../cpi/dcam/dcam_property_table.h:646 msgid "iris" msgstr "Diaphragme" #: ../cpi/dcam/dcam_property_table.h:673 msgid "focus" msgstr "Focus" #: ../cpi/dcam/dcam_property_table.h:700 msgid "temperature" msgstr "Température" #: ../cpi/dcam/dcam_property_table.h:727 msgid "trigger_mode" msgstr "Mode déclencheur" #: ../cpi/dcam/dcam_property_table.h:750 msgid "zoom" msgstr "Zoom" #. TRANSLATORS: Lens pan #: ../cpi/dcam/dcam_property_table.h:778 msgid "pan" msgstr "" #. TRANSLATORS: Lens tilt #: ../cpi/dcam/dcam_property_table.h:806 msgid "tilt" msgstr "Tilt" #: ../cpi/dcam/dcam_property_table.h:833 msgid "optical_filter" msgstr "Filtre optique" #: ../cpi/dcam/dcam_property_table.h:860 msgid "captuuality" msgstr "Qualité de l'enregistrement" #. TRANSLATORS: Camera #. hardware register #: ../cpi/dcam/dcam_property_table.h:916 msgid "register" msgstr "Registre" #: ../cpi/dcam/dcam_property_table.h:943 msgid "timeout" msgstr "Temps limite" #: ../cpi/dcam/dcam_property_table.h:969 msgid "gpio" msgstr "Entrées/Sorties" libunicap/po/ru.po0000644000175000017500000002474613164711411014676 0ustar zmoelnigzmoelnig# translation of unicap. # Copyright (C) Arne Caspari # This file is distributed under the same license as the unicap package. # Arne Caspari , 2008. # msgid "" msgstr "" "Project-Id-Version: libunicap 0.2.23\n" "Report-Msgid-Bugs-To: arne@unicap-imaging.org\n" "POT-Creation-Date: 2008-07-21 17:12+0400\n" "PO-Revision-Date: 2008-07-21 17:22+0300\n" "Last-Translator: Yury Aliaev \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../libucil/ucil_theora.c:150 msgid "Failed to initialize audio stream" msgstr "Ошибка инициализации звукового потока" #: ../libucil/ucil_theora.c:160 msgid "Failed to initialize audio encoder" msgstr "Ошибка инициализации кодировщика звука" #: ../libucil/ucil_theora.c:184 #: ../libucil/ucil_theora.c:194 #: ../libucil/ucil_theora.c:208 #: ../libucil/ucil_theora.c:220 #: ../libucil/ucil_theora.c:264 #: ../libucil/ucil_theora.c:276 #: ../libucil/ucil_theora.c:293 msgid "Invalid video stream" msgstr "Неверный видеопоток " #: ../libucil/ucil_theora.c:238 msgid "Could not create audio stream" msgstr "Невозможно создать звуковой поток" #: ../libunicapgtk/unicapgtk_device_property.c:664 msgid "Auto" msgstr "Авто" #: ../libunicapgtk/unicapgtk_device_property.c:677 msgid "One Push" msgstr "Одно нажатие" #: ../libunicapgtk/unicapgtk_device_property.c:854 msgid "Enabled" msgstr "Используется" #: ../libunicapgtk/unicapgtk_property_dialog.c:521 msgid "Update" msgstr "Обновить" #: ../libunicapgtk/unicapgtk_property_dialog.c:530 msgid "Defaults" msgstr "Параметры по умолчанию" #: ../cpi/v4l2/v4l2.c:60 #: ../cpi/v4l2/v4l2_i18n_strings.h:39 msgid "video source" msgstr "источник видеосигнала" #: ../cpi/v4l2/v4l2.c:61 msgid "video norm" msgstr "" #: ../cpi/v4l2/v4l2.c:62 #: ../cpi/v4l2/v4l2_i18n_strings.h:22 #: ../cpi/dcam/dcam_property_table.h:952 msgid "frame rate" msgstr "частота кадров" #: ../cpi/v4l2/v4l2.c:199 msgid "STK-1135 USB2 Camera Controller" msgstr "Контроллер камеры STK-1135 USB2" #: ../cpi/v4l2/v4l2.c:200 msgid "DFx 41" msgstr "DFx 41" #: ../cpi/v4l2/v4l2.c:1167 msgid "source" msgstr "источник" #: ../cpi/v4l2/v4l2.c:1305 #: ../cpi/v4l2/v4l2.c:1412 msgid "video" msgstr "видео" #: ../cpi/v4l2/v4l2_i18n_strings.h:14 msgid "anti-flicking" msgstr "устранение мерцания" #: ../cpi/v4l2/v4l2_i18n_strings.h:15 msgid "auto exposure/gain" msgstr "автоматическая экспозиция/усиление" #: ../cpi/v4l2/v4l2_i18n_strings.h:16 msgid "auto white balance" msgstr "автоматический баланс белого" #: ../cpi/v4l2/v4l2_i18n_strings.h:17 msgid "Brightness" msgstr "Яркость" #: ../cpi/v4l2/v4l2_i18n_strings.h:18 #: ../cpi/dcam/dcam_property_table.h:198 msgid "brightness" msgstr "яркость" #: ../cpi/v4l2/v4l2_i18n_strings.h:19 msgid "Contrast" msgstr "Контрастность" #: ../cpi/v4l2/v4l2_i18n_strings.h:20 msgid "contrast" msgstr "контрастность" #: ../cpi/v4l2/v4l2_i18n_strings.h:21 msgid "Exposure, Auto" msgstr "Автоматическая экспозиция" #: ../cpi/v4l2/v4l2_i18n_strings.h:23 msgid "Gain" msgstr "Усиление" #: ../cpi/v4l2/v4l2_i18n_strings.h:24 #: ../cpi/dcam/dcam_property_table.h:631 msgid "gain" msgstr "усиление" #: ../cpi/v4l2/v4l2_i18n_strings.h:25 msgid "Gamma" msgstr "Гамма" #: ../cpi/v4l2/v4l2_i18n_strings.h:26 #: ../cpi/dcam/dcam_property_table.h:576 msgid "gamma" msgstr "гамма" #: ../cpi/v4l2/v4l2_i18n_strings.h:27 msgid "horizontal flip" msgstr "отражение по горизонтали" #: ../cpi/v4l2/v4l2_i18n_strings.h:28 msgid "Hue" msgstr "Оттенок" #: ../cpi/v4l2/v4l2_i18n_strings.h:29 #: ../cpi/dcam/dcam_property_table.h:522 msgid "hue" msgstr "оттенок" #: ../cpi/v4l2/v4l2_i18n_strings.h:30 msgid "Power Line Frequency" msgstr "Частота шины питания" #: ../cpi/v4l2/v4l2_i18n_strings.h:31 msgid "resolution" msgstr "разрешение" #: ../cpi/v4l2/v4l2_i18n_strings.h:32 msgid "Saturation" msgstr "Насыщение" #: ../cpi/v4l2/v4l2_i18n_strings.h:33 #: ../cpi/dcam/dcam_property_table.h:549 msgid "saturation" msgstr "насыщение" #: ../cpi/v4l2/v4l2_i18n_strings.h:34 msgid "Sharpness" msgstr "Резкость" #: ../cpi/v4l2/v4l2_i18n_strings.h:35 #: ../cpi/dcam/dcam_property_table.h:414 msgid "sharpness" msgstr "резкость" #: ../cpi/v4l2/v4l2_i18n_strings.h:36 msgid "Shutter" msgstr "Затвор" #: ../cpi/v4l2/v4l2_i18n_strings.h:37 #: ../cpi/v4l2/tiseuvccam.c:150 #: ../cpi/v4l2/tisuvccam.c:476 #: ../cpi/dcam/dcam_property_table.h:603 msgid "shutter" msgstr "затвор" #: ../cpi/v4l2/v4l2_i18n_strings.h:38 msgid "vertical flip" msgstr "Отражение по вертикали" #: ../cpi/v4l2/v4l2_i18n_strings.h:40 msgid "White Balance Temperature, Auto" msgstr "Автоматическая балансировка цветовой температуры" #: ../cpi/v4l2/v4l2_i18n_strings.h:41 msgid "White Balance Temperature" msgstr "Цветовая температура" #: ../cpi/v4l2/v4l2_i18n_strings.h:43 msgid "YUV 4:2:2 (YUYV)" msgstr "YUV 4:2:2 (YUYV)" #: ../cpi/v4l2/v4l2_i18n_strings.h:44 msgid "Uncompressed" msgstr "Несжатое" #: ../cpi/v4l2/tiseuvccam.c:132 #: ../cpi/v4l2/tisuvccam.c:282 msgid "trigger" msgstr "триггер" #: ../cpi/v4l2/tiseuvccam.c:133 #: ../cpi/v4l2/tisuvccam.c:283 msgid "device" msgstr "Устройство" #: ../cpi/v4l2/tiseuvccam.c:151 #: ../cpi/v4l2/tisuvccam.c:143 #: ../cpi/v4l2/tisuvccam.c:171 #: ../cpi/v4l2/tisuvccam.c:227 #: ../cpi/v4l2/tisuvccam.c:255 #: ../cpi/v4l2/tisuvccam.c:312 #: ../cpi/v4l2/tisuvccam.c:477 #: ../cpi/dcam/dcam_property_table.h:47 msgid "exposure" msgstr "экспозиция" #: ../cpi/v4l2/tisuvccam.c:142 msgid "auto shutter" msgstr "автоматический затвор" #: ../cpi/v4l2/tisuvccam.c:170 msgid "auto gain" msgstr "автоматическое усиление" #: ../cpi/v4l2/tisuvccam.c:198 msgid "one push wb" msgstr "Авто баланс белого" #: ../cpi/v4l2/tisuvccam.c:199 msgid "color" msgstr "цвет" #: ../cpi/v4l2/tisuvccam.c:226 msgid "auto exposure reference" msgstr "" #: ../cpi/v4l2/tisuvccam.c:254 msgid "auto shutter maximum" msgstr "макс. значение автовыдержки" #: ../cpi/v4l2/tisuvccam.c:256 #: ../cpi/v4l2/tisuvccam.c:478 msgid "s" msgstr "с" #: ../cpi/v4l2/tisuvccam.c:311 msgid "auto exposure average frames" msgstr "" #: ../cpi/dcam/dcam_property_table.h:34 msgid "Video" msgstr "Видео" #: ../cpi/dcam/dcam_property_table.h:35 msgid "Exposure" msgstr "Экспозиция" #: ../cpi/dcam/dcam_property_table.h:36 msgid "Lens Control" msgstr "Управление объективом" #: ../cpi/dcam/dcam_property_table.h:37 msgid "Color" msgstr "Цвет" #: ../cpi/dcam/dcam_property_table.h:38 msgid "Device" msgstr "Устройство" #: ../cpi/dcam/dcam_property_table.h:44 msgid "constant low" msgstr "постоянный низкий уровень" #: ../cpi/dcam/dcam_property_table.h:45 msgid "constant high" msgstr "постоянный высокий уровень" #: ../cpi/dcam/dcam_property_table.h:46 msgid "fixed duration" msgstr "постоянная длительность" #: ../cpi/dcam/dcam_property_table.h:52 msgid "active low" msgstr "активный уровень \"0\"" #: ../cpi/dcam/dcam_property_table.h:53 msgid "active high" msgstr "активный уровень \"1\"" #: ../cpi/dcam/dcam_property_table.h:142 msgid "free running" msgstr "свободная работа" #: ../cpi/dcam/dcam_property_table.h:143 msgid "mode 0" msgstr "режим 0" #: ../cpi/dcam/dcam_property_table.h:144 msgid "mode 1" msgstr "режим 1" #: ../cpi/dcam/dcam_property_table.h:145 msgid "mode 2" msgstr "режим 2" #: ../cpi/dcam/dcam_property_table.h:146 msgid "mode 3" msgstr "режим 3" #: ../cpi/dcam/dcam_property_table.h:151 msgid "falling edge" msgstr "спад" #: ../cpi/dcam/dcam_property_table.h:152 msgid "rising edge" msgstr "фронт" #: ../cpi/dcam/dcam_property_table.h:279 msgid "strobe_mode" msgstr "режим стробирования" #: ../cpi/dcam/dcam_property_table.h:305 msgid "strobe_duration" msgstr "длительность строба" #: ../cpi/dcam/dcam_property_table.h:332 msgid "strobe_delay" msgstr "задержка строба" #: ../cpi/dcam/dcam_property_table.h:359 msgid "strobe_polarity" msgstr "полярность строба" #: ../cpi/dcam/dcam_property_table.h:387 msgid "auto_exposure" msgstr "автоматическая экспозиция" #: ../cpi/dcam/dcam_property_table.h:441 msgid "white_balance_mode" msgstr "режим баланса белого" #: ../cpi/dcam/dcam_property_table.h:468 msgid "white_balance_u" msgstr "баланс белого u" #: ../cpi/dcam/dcam_property_table.h:495 msgid "white_balance_v" msgstr "баланс белого v" #: ../cpi/dcam/dcam_property_table.h:658 msgid "iris" msgstr "диафрагма" #: ../cpi/dcam/dcam_property_table.h:685 msgid "focus" msgstr "фокус" #: ../cpi/dcam/dcam_property_table.h:712 msgid "temperature" msgstr "температура" #: ../cpi/dcam/dcam_property_table.h:740 msgid "software trigger" msgstr "программный триггер" #: ../cpi/dcam/dcam_property_table.h:767 msgid "trigger_mode" msgstr "триггерный режим" #: ../cpi/dcam/dcam_property_table.h:791 msgid "trigger_polarity" msgstr "полярность триггера" #: ../cpi/dcam/dcam_property_table.h:815 msgid "zoom" msgstr "приближение" #. TRANSLATORS: Lens pan #: ../cpi/dcam/dcam_property_table.h:843 msgid "pan" msgstr "панорамирование" #. TRANSLATORS: Lens tilt #: ../cpi/dcam/dcam_property_table.h:871 msgid "tilt" msgstr "сдвиг" #: ../cpi/dcam/dcam_property_table.h:898 msgid "optical_filter" msgstr "оптический фильтр" #: ../cpi/dcam/dcam_property_table.h:925 msgid "capture_quality" msgstr "качество записи" #. TRANSLATORS: Camera #. hardware register #: ../cpi/dcam/dcam_property_table.h:981 msgid "register" msgstr "регистр" #: ../cpi/dcam/dcam_property_table.h:1008 msgid "timeout" msgstr "время ожидания" #: ../cpi/dcam/dcam_property_table.h:1034 msgid "gpio" msgstr "входы/выходы" libunicap/po/LINGUAS0000644000175000017500000000001113164711411014710 0ustar zmoelnigzmoelnigde fr ru libunicap/po/Makevars0000644000175000017500000000342313164711411015371 0ustar zmoelnigzmoelnig# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = $(PACKAGE) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Arne Caspari # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS =arne@unicap-imaging.org # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = libunicap/src/0000755000175000017500000000000013164711411014044 5ustar zmoelnigzmoelniglibunicap/src/Makefile.am0000644000175000017500000000211413164711411016076 0ustar zmoelnigzmoelnigMAINTAINERCLEANFILES = Makefile.in INCLUDES = -I../include -I../cpi/include AM_CPPFLAGS=-DINSTALL_PREFIX="\"$(prefix)\"" -DPKGLIBDIR="\"$(libdir)/unicap$(pkg_version)\"" -DPKG_VERSION="\"@pkg_version@\"" lib_LTLIBRARIES = libunicap.la if ENABLE_STATIC_CPI libunicap_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ @RT_LIBS@ -static else libunicap_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ @RT_LIBS@ endif libunicap_la_SOURCES = \ unicap.c \ ../include/unicap_private.h \ unicap_cache.c \ check_match.c \ ../include/check_match.h \ unicap_helpers.c \ ../include/unicap_helpers.h if BUILD_V4L2 LIBV4L2=cpi/v4l2cpi/libv4l2cpi.la endif if BUILD_V4L LIBV4L=cpi/v4l/libv4l.la endif if BUILD_DCAM LIBDCAM=cpi/dcam/libdcam.la endif if BUILD_VID21394 LIBVID21394=cpi/vid21394/libvid21394.la endif if ENABLE_STATIC_CPI libunicap_la_LIBADD = \ @DL_LIBS@ \ @M_LIBS@ \ @RT_LIBS@ \ @PTHREAD_LIBS@ \ ../$(LIBV4L2) ../$(LIBV4L) ../$(LIBDCAM) ../$(LIBVID21394) else libunicap_la_LIBADD = \ @DL_LIBS@ \ @M_LIBS@ \ @RT_LIBS@ \ @PTHREAD_LIBS@ endif libunicap/src/unicap_cache.c0000644000175000017500000000340013164711411016607 0ustar zmoelnigzmoelnig/* ** unicap_cache.c ** ** Made by (Arne Caspari) ** Login ** ** Started on Fri Aug 31 19:07:15 2007 Arne Caspari */ #include "config.h" #include #define NUM_CACHE_ENTRIES 64 typedef struct { char key[64]; void *value; int refc; } unicap_cache_entry_t; static unicap_cache_entry_t g_cache[ NUM_CACHE_ENTRIES ]; static int g_use_cache = 0; void unicap_cache_init( void ) { int i; if( !g_use_cache ) { for( i = 0; i < NUM_CACHE_ENTRIES; i++ ) { g_cache[ i ].value = NULL; g_cache[ i ].refc = 0; } } g_use_cache = 1; } int unicap_cache_add( char *key, void *value ) { int i; int ret = -1; if( g_use_cache ) { for( i = 0; i < NUM_CACHE_ENTRIES; i++ ) { if( !strcpy( g_cache[ i ].key, key ) ) { ret = 1; } } if( ret < 0 ) { for( i = 0; i < NUM_CACHE_ENTRIES; i++ ) { if( !g_cache[ i ].value ) { ret = 0; strcpy( g_cache[ i ].key, key ); g_cache[ i ].refc++; g_cache[ i ].value = value; } } } } return ret; } void* unicap_cache_get( char *key ) { int i; if( g_use_cache ) { for( i = 0; i < NUM_CACHE_ENTRIES; i++ ) { if( !strcmp( g_cache[ i ].key, key ) ) { g_cache[ i ].refc++; return g_cache[ i ].value; } } } return NULL; } void *unicap_cache_unref( char *key ) { int i; void *ret = NULL; if( g_use_cache ) { for( i = 0; i < NUM_CACHE_ENTRIES; i++ ) { if( !strcmp( g_cache[ i ].key, key ) ) { g_cache[ i ].refc--; if( !g_cache[ i ].refc ) { ret = g_cache[ i ].value; } g_cache[ i ].value = NULL; } } } return ret; } libunicap/src/check_match.c0000644000175000017500000001542113164711411016444 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "check_match.h" #if UNICAP_DEBUG #define DEBUG #endif #include "debug.h" /* Returns 1 if 'device' maches on 'specifier' or 0 if it does not. Input: specifier: device: Return values: 1 0 */ int _check_device_match( unicap_device_t *specifier, unicap_device_t *device ) { if( !specifier ) { return 1; } if( strlen( specifier->identifier ) ) { if( strncmp( specifier->identifier, device->identifier, 256 ) ) { /* TRACE( "identifier mismatch: %s <> %s\n", specifier->identifier, device->identifier ); */ return 0; } else { return 1; } } if( strlen( specifier->model_name ) ) { if( strncmp( specifier->model_name, device->model_name, 256 ) ) { /* TRACE( "model name mismatch %s <> %s\n", specifier->model_name, device->model_name ); */ return 0; } } if( strlen( specifier->vendor_name ) ) { if( strncmp( specifier->vendor_name, device->vendor_name, 256 ) ) { /* TRACE( "vendor name mismatch\n" ); */ return 0; } } if( specifier->model_id != -1 ) { if( specifier->model_id != device->model_id ) { /* TRACE( "model id mismatch\n" ); */ return 0; } } if( specifier->vendor_id != -1 ) { if( specifier->vendor_id != device->vendor_id ) { /* TRACE( "vendor_id mismatch\n" ); */ return 0; } } if( strlen( specifier->cpi_layer ) ) { if( strncmp( specifier->cpi_layer, device->cpi_layer, 256 ) ) { /* TRACE( "cpi_layer mismatch\n" ); */ return 0; } } if( strlen( specifier->device ) ) { if( strncmp( specifier->device, device->device, 256 ) ) { /* TRACE( "device mismatch\n" ); */ return 0; } } return 1; } int _check_format_match( unicap_format_t *specifier, unicap_format_t *format ) { int i; /* char b[512]; */ /* size_t bs = sizeof( b ); */ if( !specifier ) { return 1; } /* unicap_describe_format( specifier, b, &bs ); */ /* printf( "spec: %s", b ); */ /* bs = sizeof( b ); */ /* unicap_describe_format( format, b, &bs ); */ /* printf( "format: %s", b ); */ if( strlen( specifier->identifier ) && strncmp( specifier->identifier, format->identifier, 256 ) ) { /* TRACE( "identifier missmatch\n" ); */ return 0; } if( ( specifier->size.width != -1 ) && ( specifier->size.width != format->size.width ) ) { int match = 0; if( format->size_count ) { for( i = 0; i < format->size_count; i++ ) { if( format->sizes[i].width == specifier->size.width ) { match = 1; } } } else { if( ( format->min_size.width <= specifier->size.width ) && ( format->max_size.width >= specifier->size.width ) ) { match = 1; } } if( !match ) { /* TRACE( "width mismatch\n" ); */ return 0; } } if( ( specifier->size.height != -1 ) && ( specifier->size.height != format->size.height ) ) { int match = 0; for( i = 0; i < format->size_count; i++ ) { if( format->sizes[i].height == specifier->size.height ) { match = 1; } } if( !match ) { if( ( format->min_size.height != -1 ) && ( specifier->size.height >= format->min_size.height ) && ( specifier->size.height <= format->max_size.height ) ) { //check the cropping size /* match = !( ( specifier->size.height - format->min_size.height ) % */ /* format->v_stepping ); */ match = 1; } } if( !match ) { /* TRACE( "height mismatch\n" ); */ return 0; } } if( ( specifier->bpp != -1 ) && ( specifier->bpp != format->bpp ) ) { /* TRACE( "bpp missmatch\n" ); */ return 0; } if( ( specifier->fourcc != 0 ) && ( specifier->fourcc != format->fourcc ) ) { /* TRACE( "fourcc missmatch\n" ); */ return 0; } if( ( specifier->min_size.width != -1 ) && ( specifier->min_size.width < format->min_size.width ) ) { /* TRACE( "min_size.w missmatch\n" ); */ return 0; } if( ( specifier->max_size.width != -1 ) && ( specifier->max_size.width > format->max_size.width ) ) { /* TRACE( "max_size.w missmatch\n" ); */ return 0; } if( ( specifier->min_size.height != -1 ) && ( specifier->min_size.height < format->min_size.height ) ) { /* TRACE( "min_size.h missmatch\n" ); */ return 0; } if( ( specifier->max_size.height != -1 ) && ( specifier->max_size.height > format->max_size.height ) ) { /* TRACE( "max_size.h missmatch\n" ); */ return 0; } if( ( specifier->h_stepping != -1 ) && ( specifier->h_stepping != format->h_stepping ) ) { /* TRACE( "h_step missmatch\n" ); */ return 0; } if( ( specifier->v_stepping != -1 ) && ( specifier->v_stepping != format->v_stepping ) ) { /* TRACE( "v_step missmatch\n" ); */ return 0; } if( ( specifier->buffer_size != -1 ) && ( specifier->buffer_size != format->buffer_size ) ) { /* TRACE( "buffer_size missmatch\n" ); */ return 0; } return 1; } int _check_property_match( unicap_property_t *specifier, unicap_property_t *property ) { if( !specifier ) { return 1; } if( strlen( specifier->identifier ) ) { if( strcmp( specifier->identifier, property->identifier ) ) { /* TRACE( "match failed\n" ); */ return 0; } } if( strlen( specifier->unit ) ) { if( strcmp( specifier->unit, property->unit ) ) { /* TRACE( "match failed\n" ); */ return 0; } } if( strlen( specifier->category ) ) { if( strcmp( specifier->category, property->category ) ) { /* TRACE( "match failed\n" ); */ return 0; } } if( specifier->value != 0 ) { if( specifier->value != property->value ) { /* TRACE( "match failed\n" ); */ return 0; } } if( specifier->range.min != 0 ) { if( specifier->range.min < property->range.min ) { /* TRACE( "match failed\n" ); */ return 0; } } if( specifier->range.max != 0 ) { if( specifier->range.max > property->range.max ) { /* TRACE( "match failed\n" ); */ return 0; } } if( specifier->stepping != 0 ) { if( specifier->stepping != property->stepping ) { /* TRACE( "match failed\n" ); */ return 0; } } return 1; } libunicap/src/unicap.c0000644000175000017500000011564213164711411015500 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if !ENABLE_STATIC_CPI #include // dynamic loader #else #include "static_cpi.h" #endif #include "unicap.h" #include "unicap_version.h" #include "unicap_private.h" #include "unicap_cpi.h" #include "unicap_helpers.h" #include "check_match.h" #include "unicap_status.h" #if UNICAP_DEBUG #define DEBUG #endif #include "debug.h" union semun_linux { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux specific) */ }; struct unicap_device_cache{ unicap_device_t device; unicap_handle_t handle; }; static unicap_handle_t unicap_copy_handle( unicap_handle_t handle ); static struct unicap_device_cache *lookup_device_cache( unicap_device_t *device ); const unsigned int unicap_major_version=UNICAP_MAJOR_VERSION; const unsigned int unicap_minor_version=UNICAP_MINOR_VERSION; const unsigned int unicap_micro_version=UNICAP_MICRO_VERSION; static int g_device_count = 0; static unicap_device_t g_devices[UNICAP_MAX_DEVICES]; static int g_filter_remote = 0; static struct unicap_device_cache g_device_cache[UNICAP_MAX_DEVICES]; static volatile int g_initialized = 0; static void unicap_initialize( void ) { int i; if( !g_initialized ){ for( i = 0; i < UNICAP_MAX_DEVICES; i++ ){ unicap_void_device( &g_device_cache[i].device ); g_device_cache[i].handle = NULL; } g_initialized = 1; } } #if ENABLE_STATIC_CPI static int g_static_cpi_initialized = 0; static void initialize_static_cpis() { if( !g_static_cpi_initialized ){ int i; #if BUILD_DCAM unicap_dcam_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_DCAM] ); #endif #if BUILD_VID21394 unicap_vid21394_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_VID21394] ); #endif #if BUILD_V4L unicap_v4l_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_V4L] ); #endif #if BUILD_V4L2 unicap_v4l2_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_V4L2] ); #endif static_cpis_s[UNICAP_STATIC_CPI_COUNT] = 0; } g_static_cpi_initialized = 1; } #endif static struct unicap_device_cache *lookup_device_cache( unicap_device_t *device ) { int i; for( i = 0; i < UNICAP_MAX_DEVICES; i++ ){ if( _check_device_match( device, &g_device_cache[i].device ) ){ return &g_device_cache[i]; } } return NULL; } static void store_device_cache( unicap_device_t *device, unicap_handle_t handle ) { int i; for( i = 0; i < UNICAP_MAX_DEVICES; i++ ){ if( g_device_cache[i].handle == NULL ){ TRACE ("Storing in cache: %s\n", device->identifier); memcpy( &g_device_cache[i].device, device, sizeof( unicap_device_t ) ); g_device_cache[i].handle = unicap_clone_handle( handle ); break; } } } static void free_device_cache_entries( void ) { int i; for( i = 0; i < UNICAP_MAX_DEVICES; i++ ){ if( g_device_cache[i].handle && ( *g_device_cache[i].handle->ref_count == 1 ) ){ unicap_close( g_device_cache[i].handle ); unicap_void_device( &g_device_cache[i].device ); g_device_cache[i].handle = NULL; } } } unicap_status_t unicap_set_filter_remote( int do_filter ) { if( do_filter ){ g_filter_remote = 1; }else{ g_filter_remote = 0; } return STATUS_SUCCESS; } static unicap_status_t _unicap_acquire_cpi_lock( int sem_id ) { #ifdef UNICAP_THREAD_LOCKING if( sem_id != -1 ){ struct sembuf sops; sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = SEM_UNDO; if( semop( sem_id, &sops, 1 ) < 0 ){ return STATUS_FAILURE; } } #endif return STATUS_SUCCESS; } static unicap_status_t _unicap_release_cpi_lock( int sem_id ) { #ifdef UNICAP_THREAD_LOCKING if( sem_id != -1 ) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = SEM_UNDO; if( semop( sem_id, &sops, 1 ) < 0 ){ return STATUS_FAILURE; } } #endif return STATUS_SUCCESS; } static void unicap_event_callback( unicap_handle_t handle, unicap_event_t event, ... ) { if( !handle->cb_info || !handle->cb_info[event].func ){ return; } switch( event ){ case UNICAP_EVENT_DEVICE_REMOVED: { handle->cb_info[event].func( event, handle, handle->cb_info[event].user_ptr ); } break; case UNICAP_EVENT_NEW_FRAME: { va_list ap; unicap_data_buffer_t *buffer; va_start( ap, event ); buffer = va_arg(ap, unicap_data_buffer_t *); va_end( ap ); handle->cb_info[event].func( event, handle, buffer, handle->cb_info[event].user_ptr ); } break; case UNICAP_EVENT_FORMAT_CHANGED: { va_list ap; unicap_format_t *format; va_start( ap, event ); format = va_arg(ap, unicap_format_t *); va_end( ap ); handle->cb_info[event].func( event, handle, format, handle->cb_info[event].user_ptr ); } break; default: { handle->cb_info[event].func( event, handle, handle->cb_info[event].user_ptr ); } break; } } unicap_status_t unicap_check_version( unsigned int major, unsigned int minor, unsigned int micro ) { unicap_status_t status = STATUS_SUCCESS; if( UNICAP_MAJOR_VERSION < major ){ status = STATUS_INCOMPATIBLE_MAJOR_VERSION; }else if( major == UNICAP_MAJOR_VERSION ){ if( UNICAP_MINOR_VERSION < minor ){ status = STATUS_INCOMPATIBLE_MINOR_VERSION; } else if( minor == UNICAP_MINOR_VERSION ){ if( UNICAP_MICRO_VERSION < micro ){ status = STATUS_INCOMPATIBLE_MICRO_VERSION; } } } return status; } unicap_status_t unicap_reenumerate_devices( int *_pcount ) { int count = 128; unicap_initialize(); unicap_real_enumerate_devices( &count ); g_device_count = count; if( _pcount ){ *_pcount = count; } return g_device_count ? STATUS_SUCCESS : STATUS_NO_DEVICE; } unicap_status_t unicap_enumerate_devices( unicap_device_t *specifier, unicap_device_t *device, int index ) { int current_index = -1; unicap_initialize(); if( g_device_count != 0){ int i; if( index >= g_device_count ){ return STATUS_NO_MATCH; } for( i = 0; i < g_device_count; i++ ){ if( _check_device_match( specifier, &g_devices[i] ) ){ current_index++; if( current_index == index ){ memcpy( device, &g_devices[i], sizeof( unicap_device_t ) ); return STATUS_SUCCESS; } } } } else { if( SUCCESS( unicap_reenumerate_devices( NULL ) ) ){ if( g_device_count ){ return unicap_enumerate_devices( specifier, device, index ); } } } return STATUS_NO_MATCH; } #if !ENABLE_STATIC_CPI static unicap_status_t enumerate_devices( int *count ) { void *dlhandle; cpi_register_t cpi_register; unicap_status_t status = STATUS_SUCCESS; struct _unicap_cpi cpi; int current_index = 0; DIR *cpi_dir; struct dirent *cpi_dirent; char *dirname; char buffer[PATH_MAX]; const char suffix[] = ".so"; strcpy( buffer, PKGLIBDIR "/cpi" ); TRACE( "cpi search path: %s, suffix: %s\n", buffer, suffix ); cpi_dir = opendir( buffer ); if( !cpi_dir ){ return STATUS_FAILURE; } dirname = buffer; while( ( cpi_dirent = readdir( cpi_dir ) ) > 0 ){ char filename[512]; int tmp_index = 0; sprintf( filename, "%s/%s", dirname, cpi_dirent->d_name ); if( ( !strstr( filename, suffix ) ) || ( strlen( strstr( filename, suffix ) ) != strlen( suffix ) ) ){ continue; } TRACE( "open cpi: %s\n", filename ); // load the cpi as a .so dlhandle = dlopen( filename, RTLD_NOW | RTLD_NODELETE); if( !dlhandle ){ /* TRACE( "cpi load: %s\n", dlerror() ); */ fprintf( stderr, "cpi load '%s': %s\n", filename, dlerror() ); continue; } cpi_register = dlsym( dlhandle, "cpi_register" ); if( !cpi_register ){ TRACE( "cpi load: %s\n", dlerror() ); dlclose( dlhandle ); continue; } memset( &cpi, 0x0, sizeof( struct _unicap_cpi ) ); cpi_register( &cpi ); if( g_filter_remote && ( cpi.cpi_flags & UNICAP_CPI_REMOTE ) ){ TRACE( "cpi load: remote cpi filtered out\n" ); dlclose( dlhandle ); continue; } if( CPI_VERSION_HI(cpi.cpi_version) > 2 ){ TRACE( "cpi load: unknown version\n" ); dlclose( dlhandle ); continue; } TRACE( "cpi.cpi_enumerate_devices: %p\n", cpi.cpi_enumerate_devices ); // look at all devices supplied by the cpi while( ( current_index < *count ) && ( SUCCESS( status = cpi.cpi_enumerate_devices( &g_devices[current_index], tmp_index ) ) ) ){ TRACE( "current_index: %d\n", current_index ); strcpy( g_devices[current_index].cpi_layer, filename ); current_index++; tmp_index++; } TRACE( "status: %08x\n", status ); dlclose( dlhandle ); } *count = current_index; closedir( cpi_dir ); return status; } #else static unicap_status_t enumerate_devices( int *count ) { int idx_cpi = 0; int idx_device = 0; unicap_status_t status = STATUS_SUCCESS; initialize_static_cpis(); while( static_cpis_s[idx_cpi] != 0 ){ struct _unicap_cpi *cpi = static_cpis_s[idx_cpi]; int idx_tmp = 0; while( ( idx_device < *count ) && ( SUCCESS( status = cpi->cpi_enumerate_devices( &g_devices[idx_device], idx_tmp++ ) ) ) ){ TRACE( "current index: %d\n", idx_device ); sprintf( g_devices[idx_device].cpi_layer, "%d", idx_cpi ); idx_device++; } TRACE( "status: %08x\n", status ); idx_cpi++; } *count = idx_device; return status; } #endif //ENABLE_STATIC_CPI unicap_status_t unicap_real_enumerate_devices( int *count ) { return enumerate_devices( count ); } #if !ENABLE_STATIC_CPI static unicap_status_t open_cpi( unicap_handle_t *unicap_handle, unicap_device_t *device ) { void *dlhandle; unicap_handle_t handle; unicap_status_t status; int i; TRACE( "open----------%s\n", device->identifier ); if( !device || !unicap_handle ){ return STATUS_INVALID_PARAMETER; } *unicap_handle = NULL; handle = malloc( sizeof( struct _unicap_handle ) ); if( !handle ){ return STATUS_NO_MEM; } // initialize data structure memset( handle, 0, sizeof( struct _unicap_handle ) ); handle->cb_info = malloc( sizeof( struct _unicap_callback_info ) * UNICAP_EVENT_LAST ); for( i = 0; i < UNICAP_EVENT_LAST; i++ ){ handle->cb_info[ i ].func = NULL; handle->cb_info[ i ].user_ptr = NULL; } handle->lock = malloc( sizeof( struct unicap_device_lock ) ); memset( handle->lock, 0x0, sizeof( struct unicap_device_lock ) ); dlhandle = dlopen( device->cpi_layer, RTLD_LAZY | RTLD_NODELETE); if( !dlhandle ){ free( handle ); return STATUS_CPI_OPEN_FAILED; } // // resolve cpi symbols // handle->cpi.cpi_register = dlsym( dlhandle, "cpi_register" ); if( !handle->cpi.cpi_register ){ TRACE( "unicap: cpi %s : INVALID_CPI\n", device->cpi_layer ); free( handle ); dlclose( dlhandle ); return STATUS_INVALID_CPI; } handle->cpi.cpi_register( &handle->cpi ); if( CPI_VERSION_HI(handle->cpi.cpi_version) > 2 ){ TRACE( "cpi_version hi: %d\n", CPI_VERSION_HI(handle->cpi.cpi_version) ); free( handle ); dlclose( dlhandle ); return STATUS_UNSUPPORTED_CPI_VERSION; } // TODO:: check capabilities // if serialized operation is requested, use a semaphore to prevent that more than one thread // could enter a cpi function at the time if( handle->cpi.cpi_flags & UNICAP_CPI_SERIALIZED ){ struct semid_ds semid; union semun_linux semun; // serialize per cpi. TODO: serialize per device optionally handle->sem_key = ftok( device->cpi_layer, 'a' ); if( handle->sem_key == -1 ){ free( handle ); dlclose( dlhandle ); return STATUS_FAILURE; } handle->sem_id = semget( handle->sem_key, 1, IPC_CREAT ); if( handle->sem_id == -1 ){ free( handle ); dlclose( dlhandle ); return STATUS_FAILURE; } semun.buf = &semid; // check if the semaphore is used the first time -> initialize it semctl( handle->sem_id, 0, IPC_STAT, semun ); if( semid.sem_otime == 0 ){ semun.val = 1; semctl( handle->sem_id, 0, SETVAL, semun ); } }else{ handle->sem_key = -1; handle->sem_id = -1; } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_open( &handle->cpi_data, device ); if( !SUCCESS( status ) ){ _unicap_release_cpi_lock( handle->sem_id ); free( handle ); dlclose( dlhandle ); return status; } _unicap_release_cpi_lock( handle->sem_id ); handle->dlhandle = dlhandle; memcpy( &handle->device, device, sizeof( unicap_device_t ) ); handle->ref_count = malloc( sizeof( int ) ); *(handle->ref_count) = 1; *unicap_handle = handle; if( handle->cpi.cpi_set_event_notify ){ handle->cpi.cpi_set_event_notify( handle->cpi_data, unicap_event_callback, unicap_copy_handle( handle ) ); } TRACE( "open handle = %p\n", handle ); return STATUS_SUCCESS; } #else static unicap_status_t open_cpi( unicap_handle_t *unicap_handle, unicap_device_t *device ) { unicap_handle_t handle; unicap_status_t status; int cpi_count; int idx_cpi; int i; TRACE( "open----------%s\n", device->identifier ); initialize_static_cpis(); if( !device || !unicap_handle ){ return STATUS_INVALID_PARAMETER; } *unicap_handle = NULL; handle = malloc( sizeof( struct _unicap_handle ) ); if( !handle ){ return STATUS_NO_MEM; } // initialize data structure memset( handle, 0, sizeof( struct _unicap_handle ) ); handle->cb_info = malloc( sizeof( struct _unicap_callback_info ) * UNICAP_EVENT_LAST ); for( i = 0; i < UNICAP_EVENT_LAST; i++ ){ handle->cb_info[ i ].func = NULL; handle->cb_info[ i ].user_ptr = NULL; } handle->lock = malloc( sizeof( struct unicap_device_lock ) ); memset( handle->lock, 0x0, sizeof( struct unicap_device_lock ) ); sscanf( device->cpi_layer, "%d", &idx_cpi ); if( ( idx_cpi < 0 ) || ( idx_cpi > UNICAP_STATIC_CPI_COUNT ) ){ free( handle ); return STATUS_INVALID_PARAMETER; } memcpy( &handle->cpi, static_cpis_s[idx_cpi], sizeof( struct _unicap_cpi ) ); handle->sem_key = -1; handle->sem_id = -1; status = handle->cpi.cpi_open( &handle->cpi_data, device ); if( !SUCCESS( status ) ){ free( handle ); return status; } handle->ref_count = malloc( sizeof( int ) ); *(handle->ref_count) = 1; *unicap_handle = handle; if( handle->cpi.cpi_set_event_notify ){ handle->cpi.cpi_set_event_notify( handle->cpi_data, unicap_event_callback, unicap_copy_handle( handle ) ); } return STATUS_SUCCESS; } #endif //ENABLE_STATIC_CPI unicap_status_t unicap_open( unicap_handle_t *unicap_handle, unicap_device_t *device ) { unicap_status_t status = STATUS_SUCCESS; struct unicap_device_cache *cache_entry; unicap_initialize(); cache_entry = lookup_device_cache( device ); if( !cache_entry || !cache_entry->handle ){ status = open_cpi( unicap_handle, device ); store_device_cache( device, *unicap_handle ); } else { *unicap_handle = unicap_clone_handle( cache_entry->handle ); TRACE( "device in cache refcount = %d\n", *cache_entry->handle->ref_count ); } return status; } void unicap_cpi_register_event_notification( void* _func, void *data, unicap_handle_t handle ) { cpi_set_event_notify_t func = (cpi_set_event_notify_t)_func; func( data, unicap_event_callback, unicap_clone_handle( handle ) ); } /* Create a new instance of an unicap handle and increase ref count. Input: handle Output: A copy of handle; ref count increased */ unicap_handle_t unicap_clone_handle( unicap_handle_t handle ) { unicap_handle_t cloned_handle; if( !handle ){ return NULL; } cloned_handle = malloc( sizeof( struct _unicap_handle ) ); if( !cloned_handle ){ return NULL; } _unicap_acquire_cpi_lock( handle->sem_id ); memcpy( cloned_handle, handle, sizeof( struct _unicap_handle ) ); *(handle->ref_count) = *(handle->ref_count) + 1; _unicap_release_cpi_lock( handle->sem_id ); TRACE( "clone handle = %p: handle = %p refcount = %d\n", cloned_handle, handle, *(handle->ref_count) ); return cloned_handle; } /** * Create a new unicap_handle instance WITHOUT incrementing refcount * @handle: handle to copy * * Returns: copy of handle */ static unicap_handle_t unicap_copy_handle( unicap_handle_t handle ) { unicap_handle_t cloned_handle; if( !handle ){ return NULL; } cloned_handle = malloc( sizeof( struct _unicap_handle ) ); if( !cloned_handle ){ return NULL; } memcpy( cloned_handle, handle, sizeof( struct _unicap_handle ) ); return cloned_handle; } unicap_status_t unicap_close( unicap_handle_t handle ) { if( *(handle->ref_count) == 0 ){ TRACE( "Tried to close a handle with ref_count == 0!\n" ); return STATUS_FAILURE; } *(handle->ref_count) = *(handle->ref_count) - 1; TRACE( "close: handle = %p new refcount = %d\n", handle, *(handle->ref_count ) ); if( *(handle->ref_count) == 1 ){ free_device_cache_entries(); free( handle ); return STATUS_SUCCESS; } if( *(handle->ref_count) == 0 ){ unicap_unlock_properties( handle ); unicap_unlock_stream( handle ); // free resources _unicap_acquire_cpi_lock( handle->sem_id ); handle->cpi.cpi_capture_stop( handle->cpi_data ); handle->cpi.cpi_close( handle->cpi_data ); if( handle->dlhandle ){ dlclose( handle->dlhandle ); } _unicap_release_cpi_lock( handle->sem_id ); free( handle->ref_count ); free( handle->cb_info ); free( handle->lock ); } free( handle ); return STATUS_SUCCESS; } unicap_status_t unicap_get_device( unicap_handle_t handle, unicap_device_t *device ) { if( !handle || !device ){ return STATUS_INVALID_PARAMETER; } memcpy( device, &handle->device, sizeof( unicap_device_t ) ); return STATUS_SUCCESS; } unicap_status_t unicap_reenumerate_formats( unicap_handle_t handle, int *count ) { unicap_status_t status; status = handle->cpi.cpi_reenumerate_formats( handle->cpi_data, count ); return status; } unicap_status_t unicap_enumerate_formats( unicap_handle_t handle, unicap_format_t *specifier, unicap_format_t *format, int index ) { int current_index = -1; int tmp_index = 0; unicap_status_t status = STATUS_NO_MATCH; if( !handle ){ TRACE( "handle is NULL\n" ); return STATUS_INVALID_PARAMETER; } TRACE( "unicap_enumerate_formats, index: %d\n", index ); _unicap_acquire_cpi_lock( handle->sem_id ); while( ( current_index != index ) && ( ( status = handle->cpi.cpi_enumerate_formats( handle->cpi_data, format, tmp_index ) ) == STATUS_SUCCESS ) ){ if( _check_format_match( specifier, format ) ){ current_index++; } tmp_index++; } _unicap_release_cpi_lock( handle->sem_id ); return status; } unicap_status_t unicap_set_format( unicap_handle_t handle, unicap_format_t *format ) { unicap_status_t status; if( !format ){ return STATUS_INVALID_PARAMETER; } if( !strlen( format->identifier ) ){ return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_set_format( handle->cpi_data, format ); _unicap_release_cpi_lock( handle->sem_id ); if( SUCCESS( status ) ){ unicap_event_callback( handle, UNICAP_EVENT_FORMAT_CHANGED, format ); } return status; } unicap_status_t unicap_get_format( unicap_handle_t handle, unicap_format_t *format ) { unicap_status_t status; if( !format ){ return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_get_format( handle->cpi_data, format ); _unicap_release_cpi_lock( handle->sem_id ); return status; } unicap_status_t unicap_reenumerate_properties( unicap_handle_t handle, int *_pcount ) { unicap_status_t status; int count; status = handle->cpi.cpi_reenumerate_properties( handle->cpi_data, &count ); if( _pcount ){ *_pcount = count; } return status; } unicap_status_t unicap_enumerate_properties( unicap_handle_t handle, unicap_property_t *specifier, unicap_property_t *property, int index ) { int current_index = -1; int tmp_index = 0; unicap_status_t status; if( !property || !handle || ( index < 0 ) ){ return STATUS_INVALID_PARAMETER; } /* TRACE( "enumerate properties: %d\n", index ); */ _unicap_acquire_cpi_lock( handle->sem_id ); while( ( current_index != index ) && ( ( status = handle->cpi.cpi_enumerate_properties( handle->cpi_data, property, tmp_index ) ) == STATUS_SUCCESS ) ){ /* TRACE( "%s <> %s: %d\n", specifier->identifier, property->identifier, _check_property_match( specifier, property ) ); */ if( _check_property_match( specifier, property ) ){ current_index++; } tmp_index++; } _unicap_release_cpi_lock( handle->sem_id ); return status; } unicap_status_t unicap_set_property( unicap_handle_t handle, unicap_property_t *property ) { unicap_status_t status; if( !handle || ! property ){ TRACE( "invalid param\n" ); return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_set_property( handle->cpi_data, property ); _unicap_release_cpi_lock( handle->sem_id ); return status; } unicap_status_t unicap_set_property_value( unicap_handle_t handle, char *identifier, double value ) { unicap_status_t status; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } prop.value = value; prop.flags = UNICAP_FLAGS_MANUAL; prop.flags_mask = UNICAP_FLAGS_MANUAL; return unicap_set_property( handle, &prop ); } unicap_status_t unicap_set_property_manual( unicap_handle_t handle, char *identifier ) { unicap_status_t status; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } status = unicap_get_property( handle, &prop ); if( !SUCCESS( status ) ){ return status; } prop.flags = UNICAP_FLAGS_MANUAL; prop.flags_mask = UNICAP_FLAGS_MANUAL; return unicap_set_property( handle, &prop ); } unicap_status_t unicap_set_property_auto( unicap_handle_t handle, char *identifier ) { unicap_status_t status; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } status = unicap_get_property( handle, &prop ); if( !SUCCESS( status ) ){ return status; } prop.flags = UNICAP_FLAGS_AUTO; prop.flags_mask = UNICAP_FLAGS_AUTO; return unicap_set_property( handle, &prop ); } unicap_status_t unicap_set_property_one_push( unicap_handle_t handle, char *identifier ) { unicap_status_t status; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } status = unicap_get_property( handle, &prop ); if( !SUCCESS( status ) ) { return status; } prop.flags = UNICAP_FLAGS_ONE_PUSH; prop.flags_mask = UNICAP_FLAGS_ONE_PUSH; return unicap_set_property( handle, &prop ); } unicap_status_t unicap_get_property( unicap_handle_t handle, unicap_property_t *property ) { unicap_status_t status = STATUS_SUCCESS; if( !handle || !property ){ return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_get_property( handle->cpi_data, property ); _unicap_release_cpi_lock( handle->sem_id ); return status; } unicap_status_t unicap_get_property_value( unicap_handle_t handle, const char *identifier, double *value ) { if( !handle || !identifier ) { return STATUS_INVALID_PARAMETER; } unicap_status_t status = STATUS_SUCCESS; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } status = unicap_get_property( handle, &prop ); if( !SUCCESS( status ) ){ return STATUS_FAILURE; } if( ( prop.type != UNICAP_PROPERTY_TYPE_RANGE ) && ( prop.type != UNICAP_PROPERTY_TYPE_VALUE_LIST ) ){ return STATUS_INVALID_PARAMETER; } *value = prop.value; return status; } unicap_status_t unicap_get_property_menu( unicap_handle_t handle, const char *identifier, char **value ) { static char menu_item[128]; if( !handle || !identifier ){ return STATUS_INVALID_PARAMETER; } unicap_status_t status = STATUS_SUCCESS; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } status = unicap_get_property( handle, &prop ); if( !SUCCESS( status ) ){ return STATUS_FAILURE; } if( prop.type != UNICAP_PROPERTY_TYPE_MENU ){ return STATUS_INVALID_PARAMETER; } strcpy( menu_item, prop.menu_item ); *value = menu_item; return status; } unicap_status_t unicap_get_property_auto( unicap_handle_t handle, const char *identifier, int *enabled ) { if( !handle || !identifier ){ return STATUS_INVALID_PARAMETER; } unicap_status_t status = STATUS_SUCCESS; unicap_property_t spec, prop; unicap_void_property( &spec ); unicap_void_property( &prop ); strcpy( spec.identifier, identifier ); status = unicap_enumerate_properties( handle, &spec, &prop, 0 ); if( !SUCCESS( status ) ){ return status; } status = unicap_get_property( handle, &prop ); if( !SUCCESS( status ) ){ return STATUS_FAILURE; } *enabled = ( prop.flags & UNICAP_FLAGS_AUTO ) ? 1 : 0; return status; } unicap_status_t unicap_start_capture( unicap_handle_t handle ) { unicap_status_t status = STATUS_SUCCESS; if( !handle ){ TRACE( "Invalid parameter\n" ); return STATUS_INVALID_PARAMETER; } if( !handle->lock->have_stream_lock ){ status = unicap_lock_stream( handle ); if( SUCCESS( status ) ){ handle->lock->temporary_stream_lock = 1; } } if( SUCCESS( status ) ){ TRACE( "Capture start...\n" ); _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_capture_start( handle->cpi_data ); _unicap_release_cpi_lock( handle->sem_id ); }else{ TRACE( "FAILED TO GET STREAM LOCK\n\n\n\n\n\n" ); } return status; } unicap_status_t unicap_stop_capture( unicap_handle_t handle ) { unicap_status_t status = STATUS_SUCCESS; if( !handle ){ return STATUS_INVALID_PARAMETER; } if( !handle->lock->have_stream_lock ){ status = STATUS_PERMISSION_DENIED; }else{ if( handle->lock->temporary_stream_lock ){ handle->lock->temporary_stream_lock = 0; unicap_unlock_stream( handle ); } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_capture_stop( handle->cpi_data ); _unicap_release_cpi_lock( handle->sem_id ); } return status; } unicap_status_t unicap_queue_buffer( unicap_handle_t handle, unicap_data_buffer_t *buffer ) { unicap_status_t status = STATUS_SUCCESS; if( !handle || !buffer ){ TRACE( "Invalid parameter\n" ); return STATUS_INVALID_PARAMETER; } if( !handle->lock->have_stream_lock ){ status = STATUS_PERMISSION_DENIED; }else{ _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_queue_buffer( handle->cpi_data, buffer ); _unicap_release_cpi_lock( handle->sem_id ); } return status; } unicap_status_t unicap_dequeue_buffer( unicap_handle_t handle, unicap_data_buffer_t **buffer ) { unicap_status_t status; if( !handle || !buffer ){ return STATUS_INVALID_PARAMETER; } if( !handle->lock->have_stream_lock && unicap_is_stream_locked( &handle->device ) ){ status = STATUS_PERMISSION_DENIED; }else{ _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_dequeue_buffer( handle->cpi_data, buffer ); _unicap_release_cpi_lock( handle->sem_id ); } return status; } unicap_status_t unicap_wait_buffer( unicap_handle_t handle, unicap_data_buffer_t **buffer ) { unicap_status_t status = STATUS_SUCCESS; if( !handle || !buffer ){ TRACE( "!handle || !buffer\n" ); return STATUS_INVALID_PARAMETER; } if( !handle->lock->have_stream_lock ){ status = STATUS_PERMISSION_DENIED; }else{ _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_wait_buffer( handle->cpi_data, buffer ); _unicap_release_cpi_lock( handle->sem_id ); } return status; } unicap_status_t unicap_poll_buffer( unicap_handle_t handle, int *count ) { unicap_status_t status = STATUS_SUCCESS; if( !handle || !count ){ return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); status = handle->cpi.cpi_poll_buffer( handle->cpi_data, count ); _unicap_release_cpi_lock( handle->sem_id ); return status; } static key_t uidtok( char *string ) { int i; key_t key = 0x00345678; for( i = 0; string[i] != 0; i++ ){ key = key ^ ( string[i] << ( i%3 ) ); } return key; } int unicap_is_stream_locked( unicap_device_t *device ) { key_t key; int sem_id; int val; char uid[2048]; unicap_initialize(); #ifndef UNICAP_THREAD_LOCKING return 0; #endif sprintf( uid, "%s", device->identifier ); key = uidtok( uid ); /* key = uidtok( device->identifier ); */ sem_id = semget( key, 1, S_IRWXU | S_IRWXG | S_IRWXO ); if( sem_id == -1 ){ return 0; } val = semctl( sem_id, 0, GETVAL ) ? 0 : UNICAP_FLAGS_LOCKED; if( val == UNICAP_FLAGS_LOCKED ){ struct unicap_device_cache *cache_entry; cache_entry = lookup_device_cache( device ); if( cache_entry && cache_entry->handle ){ if( cache_entry->handle->lock->have_stream_lock ){ val |= UNICAP_FLAGS_LOCK_CURRENT_PROCESS; } } } TRACE( "STREAM IS LOCKED %s%s >>>> %d (%d) key + %d\n", device->identifier, device->cpi_layer, val == 0, val, key ); return val; } unicap_status_t unicap_lock_stream( unicap_handle_t handle ) { unicap_status_t status = STATUS_SUCCESS; key_t key; int sem_id; char uid[2048]; #ifndef UNICAP_THREAD_LOCKING handle->lock->have_stream_lock = 1; return STATUS_SUCCESS; #endif sprintf( uid, "%s", handle->device.identifier ); key = uidtok( uid ); if( !handle->lock->have_stream_lock ){ struct semid_ds semds; union semun_linux semun; sem_id = semget( key, 1, IPC_CREAT | S_IRWXU | S_IRWXG | S_IRWXO); if( sem_id == -1 ){ return STATUS_FAILURE; } // check if the semaphore is used the first time -> initialize it semun.buf = &semds; semds.sem_otime = 0; semctl( sem_id, 0, IPC_STAT, semun ); if( semds.sem_otime == 0 ){ struct sembuf sops; semun.val = 1; semctl( sem_id, 0, SETVAL, semun ); sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = SEM_UNDO|IPC_NOWAIT; _unicap_acquire_cpi_lock( handle->sem_id ); if( semop( sem_id, &sops, 1 ) < 0 ){ status = STATUS_PERMISSION_DENIED; }else{ handle->lock->stream_sem_id = sem_id; handle->lock->have_stream_lock = 1; } _unicap_release_cpi_lock( handle->sem_id ); }else{ struct sembuf sops; sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = SEM_UNDO|IPC_NOWAIT; _unicap_acquire_cpi_lock( handle->sem_id ); if( semop( sem_id, &sops, 1 ) < 0 ){ status = STATUS_PERMISSION_DENIED; }else{ handle->lock->stream_sem_id = sem_id; handle->lock->have_stream_lock = 1; } _unicap_release_cpi_lock( handle->sem_id ); } } TRACE( "LOCK STREAM >>>> %d key = %d\n", handle->lock->have_stream_lock, key ); return status; } unicap_status_t unicap_unlock_stream( unicap_handle_t handle ) { unicap_status_t status = STATUS_SUCCESS; #ifndef UNICAP_THREAD_LOCKING handle->lock->have_stream_lock = 0; return STATUS_SUCCESS; #endif if( handle->lock->have_stream_lock ){ struct sembuf sops; sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = SEM_UNDO; if( semop( handle->lock->stream_sem_id, &sops, 1 ) < 0 ){ status = STATUS_FAILURE; }else{ handle->lock->have_stream_lock = 0; } }else{ status = STATUS_PERMISSION_DENIED; } TRACE( "UNLOCK STREAM >>>> %d\n", handle->lock->have_stream_lock ); return status; } unicap_status_t unicap_lock_properties( unicap_handle_t handle ) { unicap_status_t status = STATUS_FAILURE; return status; } unicap_status_t unicap_unlock_properties( unicap_handle_t handle ) { unicap_status_t status = STATUS_SUCCESS; return status; } unicap_status_t unicap_register_callback( unicap_handle_t handle, unicap_event_t event, unicap_callback_t func, void *user_ptr ) { unicap_status_t status = STATUS_FAILURE; TRACE( "register callback: %p\n", func ); if( ( event < UNICAP_EVENT_FIRST ) || ( event >= UNICAP_EVENT_LAST ) ){ return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); if( !handle->cb_info || ( handle->cb_info[event].func != NULL ) ){ status = STATUS_FAILURE; }else{ handle->cb_info[event].func = func; handle->cb_info[event].user_ptr = user_ptr; status = STATUS_SUCCESS; } _unicap_release_cpi_lock( handle->sem_id ); return status; } unicap_status_t unicap_unregister_callback( unicap_handle_t handle, unicap_event_t event ) { unicap_status_t status = STATUS_FAILURE; if( ( event < UNICAP_EVENT_FIRST ) || ( event >= UNICAP_EVENT_LAST ) ){ return STATUS_INVALID_PARAMETER; } _unicap_acquire_cpi_lock( handle->sem_id ); if( handle->cb_info[event].func == NULL ){ status = STATUS_FAILURE; }else{ handle->cb_info[event].func = NULL; handle->cb_info[event].user_ptr = NULL; status = STATUS_SUCCESS; } _unicap_release_cpi_lock( handle->sem_id ); return status; } int unicap_get_ref_count( unicap_handle_t handle ) { return *handle->ref_count; } unicap_data_buffer_t *unicap_data_buffer_new( unicap_format_t *format ) { unicap_data_buffer_t *buffer; buffer = malloc( sizeof( unicap_data_buffer_t) ); memset( buffer, 0x0, sizeof( unicap_data_buffer_t ) ); unicap_copy_format( &buffer->format, format ); buffer->buffer_size = buffer->format.buffer_size; buffer->data = malloc( buffer->buffer_size ); buffer->priv = malloc( sizeof( unicap_data_buffer_private_t ) ); memset (buffer->priv, 0x0, sizeof (unicap_data_buffer_private_t) ); sem_init( &buffer->priv->lock, 0, 1 ); return buffer; } void unicap_data_buffer_init( unicap_data_buffer_t *buffer, unicap_format_t *format, unicap_data_buffer_init_data_t *init_data ) { unicap_copy_format( &buffer->format, format ); if (!buffer->priv){ buffer->priv = malloc( sizeof( unicap_data_buffer_private_t ) ); sem_init( &buffer->priv->lock, 0, 1 ); } buffer->priv->ref_count = 0; buffer->priv->free_func = init_data->free_func; buffer->priv->free_func_data = init_data->free_func_data; buffer->priv->ref_func = init_data->ref_func; buffer->priv->ref_func_data = init_data->ref_func_data; buffer->priv->unref_func = init_data->unref_func; buffer->priv->unref_func_data = init_data->unref_func_data; } void unicap_data_buffer_free( unicap_data_buffer_t *buffer ) { sem_wait( &buffer->priv->lock ); if( buffer->priv->ref_count > 0 ){ /* TRACE( "freeing a buffer with refcount = %d!!!\n", buffer->private.refcount ); */ } if( buffer->priv->free_func ){ buffer->priv->free_func( buffer, buffer->priv->free_func_data ); } sem_destroy( &buffer->priv->lock ); if (buffer->data) free( buffer->data ); free( buffer ); } unicap_status_t unicap_data_buffer_ref( unicap_data_buffer_t *buffer ) { sem_wait( &buffer->priv->lock ); buffer->priv->ref_count++; sem_post( &buffer->priv->lock ); return STATUS_SUCCESS; } unicap_status_t unicap_data_buffer_unref( unicap_data_buffer_t *buffer ) { unicap_status_t status = STATUS_SUCCESS; sem_wait( &buffer->priv->lock ); if( buffer->priv->ref_count > 0 ){ buffer->priv->ref_count--; if (buffer->priv->unref_func){ sem_post (&buffer->priv->lock); buffer->priv->unref_func (buffer, buffer->priv->unref_func_data); return STATUS_SUCCESS; } if (buffer->priv->ref_count == 0 ){ unicap_data_buffer_free( buffer ); } }else{ TRACE( "unref of a buffer with refcount <= 0!" ); status = STATUS_FAILURE; } sem_post (&buffer->priv->lock); return status; } unsigned int unicap_data_buffer_get_refcount( unicap_data_buffer_t *buffer ) { return buffer->priv->ref_count; } void *unicap_data_buffer_set_user_data( unicap_data_buffer_t *buffer, void *data ) { void *old_data = buffer->priv->user_data; buffer->priv->user_data = data; return old_data; } void *unicap_data_buffer_get_user_data( unicap_data_buffer_t *buffer ) { return buffer->priv->user_data; } libunicap/src/unicap_helpers.c0000644000175000017500000001621113164711411017212 0ustar zmoelnigzmoelnig/* unicap Copyright (C) 2004 Arne Caspari This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "config.h" #include #include #if UNICAP_DEBUG #define DEBUG #endif #include "debug.h" unicap_status_t unicap_void_device( unicap_device_t *device ) { if( !device ) { return STATUS_INVALID_PARAMETER; } memset( device, 0, sizeof( unicap_device_t ) ); strcpy( device->identifier, "" ); strcpy( device->model_name, "" ); strcpy( device->vendor_name, "" ); device->model_id = -1; device->vendor_id = -1; strcpy( device->cpi_layer, "" ); strcpy( device->device, "" ); return STATUS_SUCCESS; } unicap_status_t unicap_void_format( unicap_format_t *format ) { if( !format ) { return STATUS_INVALID_PARAMETER; } memset( format, 0x0, sizeof( unicap_format_t ) ); strcpy( format->identifier, "" ); format->size.width = format->size.height = format->bpp = -1; format->fourcc = 0; format->min_size.width = format->max_size.width = format->min_size.height = format->max_size.height = -1; format->h_stepping = format->v_stepping = -1; format->buffer_size = -1; format->buffer_type = UNICAP_BUFFER_TYPE_USER; return STATUS_SUCCESS; } unicap_status_t unicap_void_property( unicap_property_t *property ) { if( !property ) { return STATUS_INVALID_PARAMETER; } memset( property, 0x0, sizeof( unicap_property_t ) ); strcpy( property->identifier, "" ); strcpy( property->unit, "" ); strcpy( property->category, "" ); property->value = 0.0f; property->range.min = 0.0f; property->range.max = 0.0f; property->stepping = 0.0f; property->flags = 0; property->flags_mask = 0; return STATUS_SUCCESS; } unicap_status_t unicap_describe_device( unicap_device_t *device, char *buffer, size_t *buffer_size ) { char tmp_buffer[ 512 ]; sprintf( tmp_buffer, "Device id: %s\n"\ "Model name: %s\n"\ "Vendor name: %s\n"\ "Model id: %llu\n"\ "Vendor id: %u ( 0x%x )\n" \ "cpi: %s\n"\ "device: %s\n", device->identifier, device->model_name, device->vendor_name, device->model_id, device->vendor_id, device->vendor_id, device->cpi_layer, device->device ); strncpy( buffer, tmp_buffer, (*buffer_size)-1 ); return STATUS_SUCCESS; } unicap_status_t unicap_describe_format( unicap_format_t *format, char *buffer, size_t *buffer_size ) { char tmp_buffer[512]; sprintf( tmp_buffer, "Format name: %s\n"\ "width: %d\n"\ "height: %d\n"\ "bpp: %d\n"\ "fourcc: %c%c%c%c\n"\ "min_width: %d\n"\ "min_height: %d\n"\ "max_width: %d\n"\ "max_height: %d\n"\ "h_stepping: %d\n"\ "v_stepping: %d\n", format->identifier, format->size.width, format->size.height, format->bpp, format->fourcc, format->fourcc>>8, format->fourcc>>16, format->fourcc>>24, format->min_size.width, format->min_size.height, format->max_size.width, format->max_size.height, format->h_stepping, format->v_stepping ); strncpy( buffer, tmp_buffer, *buffer_size ); return STATUS_SUCCESS; } unicap_format_t *unicap_copy_format( unicap_format_t *dest, const unicap_format_t *src ) { strcpy( dest->identifier, src->identifier ); memcpy( &dest->size, &src->size, sizeof( unicap_rect_t ) ); memcpy( &dest->min_size, &src->min_size, sizeof( unicap_rect_t ) ); memcpy( &dest->max_size, &src->max_size, sizeof( unicap_rect_t ) ); dest->h_stepping = src->h_stepping; dest->v_stepping = src->v_stepping; dest->sizes = src->sizes; dest->size_count = src->size_count; dest->bpp = src->bpp; dest->fourcc = src->fourcc; dest->flags = src->flags; dest->buffer_types = src->buffer_types; dest->buffer_size = src->buffer_size; dest->buffer_type = src->buffer_type; return dest; } unicap_property_t *unicap_copy_property( unicap_property_t *dest, const unicap_property_t *src ) { strcpy( dest->identifier, src->identifier ); strcpy( dest->category, src->category ); strcpy( dest->unit, src->unit ); dest->relations = src->relations; dest->relations_count = src->relations_count; dest->type = src->type; switch( src->type ){ case UNICAP_PROPERTY_TYPE_MENU: { strcpy( dest->menu_item, src->menu_item ); dest->menu.menu_items = src->menu.menu_items; dest->menu.menu_item_count = src->menu.menu_item_count; } break; case UNICAP_PROPERTY_TYPE_VALUE_LIST: { dest->value = src->value; dest->value_list.values = src->value_list.values; dest->value_list.value_count = src->value_list.value_count; } break; case UNICAP_PROPERTY_TYPE_RANGE: { dest->value = src->value; dest->range.min = src->range.min; dest->range.max = src->range.max; } break; default: break; } dest->stepping = src->stepping; dest->flags = src->flags; dest->flags_mask = src->flags_mask; dest->property_data = src->property_data; dest->property_data_size = src->property_data_size; return dest; } unicap_property_t *unicap_copy_property_nodata( unicap_property_t *dest, unicap_property_t *src ) { strcpy( dest->identifier, src->identifier ); strcpy( dest->category, src->category ); strcpy( dest->unit, src->unit ); dest->relations = src->relations; dest->relations_count = src->relations_count; dest->type = src->type; switch( src->type ) { case UNICAP_PROPERTY_TYPE_MENU: { strcpy( dest->menu_item, src->menu_item ); dest->menu.menu_items = src->menu.menu_items; dest->menu.menu_item_count = src->menu.menu_item_count; } break; case UNICAP_PROPERTY_TYPE_VALUE_LIST: { dest->value = src->value; dest->value_list.values = src->value_list.values; dest->value_list.value_count = src->value_list.value_count; } break; case UNICAP_PROPERTY_TYPE_RANGE: { dest->value = src->value; dest->range.min = src->range.min; dest->range.max = src->range.max; } break; default: break; } dest->stepping = src->stepping; dest->flags = src->flags; dest->flags_mask = src->flags_mask; return dest; } unicap_status_t unicap_describe_property( unicap_property_t *property, char *buffer, size_t *buffer_size ) { char tmp_buffer[512]; sprintf( tmp_buffer, "Property name: %s\n"\ "class: %s\n"\ "unit: %s\n"\ "value: %g\n"\ "range: min: %g\n"\ " max: %g\n"\ "stepping: %g\n"\ "property data size: %d\n", property->identifier, property->category, property->unit, property->value, property->range.min, property->range.max, property->stepping, property->property_data_size ); strncpy( buffer, tmp_buffer, *buffer_size ); return STATUS_SUCCESS; }