[artoolkit-commits] artoolkit/lib/SRC/VideoLinux1394Cam video.c, 1.5, 1.6
Optical marker tracking and overlay for augmented reality.
Brought to you by:
philip_lamb
From: Wayne P. <ti...@us...> - 2006-09-04 08:43:15
|
Update of /cvsroot/artoolkit/artoolkit/lib/SRC/VideoLinux1394Cam In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv25008 Modified Files: video.c Log Message: This is a major change which includes a number of new features. I have added support for Bayer image decoding, which is needed to get colour images from high-end cameras like those from Point Gray like the Dragonfly. This support was added by integrating in files from the grabdma demo from Point Gray. It is basically done transparently and it will auto-detect the type of camera that you have and use this code if the camera shows up as being mono. A number of other patches were also merged in, fixing up various little bugs, incorrect exit codes, better error messages, and so forth. Also, the licensing information was updated in this file to reflect that the VideoLinux1394 code (but nothing else) is dual-licensed under LGPL and GPL. You can chose the license of your choice. I asked permission from all the copyright holders (Kato, Kiyokawa, and myself Piekarski) and we all agreed that it was ok to do this. So the VideoLinux1394 code can be used in other LGPL projects as well. Index: video.c =================================================================== RCS file: /cvsroot/artoolkit/artoolkit/lib/SRC/VideoLinux1394Cam/video.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** video.c 23 May 2006 01:42:41 -0000 1.5 --- video.c 4 Sep 2006 08:43:12 -0000 1.6 *************** *** 1,2 **** --- 1,46 ---- + /* + 1394 Linux Firewire Digital Camera Interface + Copyright (C) 2002 - 2006 + Kiyoshi Kiyokawa (ki...@cr...) + Hirokazu Kato (ka...@sy...) + Wayne Piekarski (wa...@cs...) + + $Id$ + This source file is dual licensed under either the GPL or the LGPL license + by the authors of this software. + + -- + + 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 + + -- + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + /* * Revision: 1.0 Date: 2002/01/01 *************** *** 13,18 **** * - Support for changing of various 1394 camera properties * * Revision 1.1.1 Date: 2005/03/14 ! * Patch by Henrik Erkkonen to support version 11 of libdc1394. * */ --- 57,75 ---- * - Support for changing of various 1394 camera properties * + * * Revision 1.1.1 Date: 2005/03/14 ! * - Patch by Henrik Erkkonen to support version 11 of libdc1394. ! * - (Removed in later 1.3 changes by Wayne) ! * ! * ! * Revision: 1.2 Date: 2005/07/20 ! * Modifications by Wayne Piekarski ( wa...@cs... ) ! * - Added support for Bayer image tiling for Point Grey DragonFly cameras ! * ! * ! * Revision: 1.3 Date: 2006/09/4 ( wa...@cs... ) ! * - Stabilised interfaces around latest libdc1394 libraries ! * - Added various other cleanups and bug fixes to make the code more stable ! * - Added licensing allowing LGPL or existing GPL with permission from original authors * */ *************** *** 46,51 **** /* ----------------------- MAKE ANY #define CHANGES HERE ONLY -------------------------------- */ ! /* This define controls if we use the new or old libDC1394 API functions. The new code is much ! more stable for multiple cameras and so is recommended */ // #define LIBDC_8 // #define LIBDC_9 --- 103,109 ---- /* ----------------------- MAKE ANY #define CHANGES HERE ONLY -------------------------------- */ ! /* This define controls if we use the new or old libDC1394 API functions. In the past there were ! many development releases, but the latest 1.0.0 release is stable and modern Linux distributions ! have all standardised on this, so there is no need to make changes here any more. */ // #define LIBDC_8 // #define LIBDC_9 *************** *** 68,82 **** #ifdef LIBDC_9 ! #warning Compiling using the newer and safer 0.9.1 libDC library (multiple camera support) - debian: libdc1394-9-dev #define LIBDC_DEF #endif #ifdef LIBDC_10 ! #warning Compiling using the newer and safer 0.9.5 libDC library (multiple camera support) - debian: libdc1394-10-dev #define LIBDC_DEF #endif #ifdef LIBDC_11 ! #warning Compiling using the 1.0.0 libDC library #define LIBDC_DEF #endif --- 126,140 ---- #ifdef LIBDC_9 ! #warning Compiling using an older 0.9.1 libDC library (multiple camera support) - debian: libdc1394-9-dev #define LIBDC_DEF #endif #ifdef LIBDC_10 ! #warning Compiling using an older 0.9.5 libDC library (multiple camera support) - debian: libdc1394-10-dev #define LIBDC_DEF #endif #ifdef LIBDC_11 ! // #warning Compiling using the stable 1.0.0 libDC library (multiple camera support) - debian: libdc1394-11-dev #define LIBDC_DEF #endif *************** *** 89,92 **** --- 147,157 ---- + /* Here are some extra definitions to support Point Grey DragonFly cameras */ + #include "conversions.h" + int ar2Video_dragonfly = -1; + + + + static AR2VideoParamT *gVid = NULL; *************** *** 110,120 **** int arVideoClose( void ) { ! int result; ! ! if( gVid == NULL ) return -1; ! ! result = ar2VideoClose(gVid); ! gVid = NULL; ! return (result); } --- 175,185 ---- int arVideoClose( void ) { ! int result; ! ! if( gVid == NULL ) return -1; ! ! result = ar2VideoClose(gVid); ! gVid = NULL; ! return (result); } *************** *** 184,188 **** printf(" (value must be a legal value for this parameter - use coriander to find what they are\n"); printf("\n"); ! return 0; } --- 249,253 ---- printf(" (value must be a legal value for this parameter - use coriander to find what they are\n"); printf("\n"); ! return 0; } *************** *** 196,200 **** char *a, line[256]; int i; ! int brightness = -1; int iris = -1; --- 261,265 ---- char *a, line[256]; int i; ! int brightness = -1; int iris = -1; *************** *** 216,220 **** vid->debug = 0; vid->status = 0; ! a = config; if( a != NULL) { --- 281,287 ---- vid->debug = 0; vid->status = 0; ! ! printf ("Processing config string [%s]\n", config); ! a = config; if( a != NULL) { *************** *** 301,304 **** --- 368,374 ---- vid->debug = 1; } + else if( strncmp( a, "-adjust", 7 ) == 0 ) { + /* Do nothing - this is for V4L compatibility */ + } else { ar2VideoDispOption(); *************** *** 310,336 **** } } ! if( initFlag == 0 ) { if( ar2Video1394Init(vid->debug, &vid->card, &vid->node) < 0 ) ! exit(0); initFlag = 1; ! } ! ! switch( vid->mode ) { ! case VIDEO_MODE_320x240_YUV422: ! vid->int_mode = MODE_320x240_YUV422; ! break; ! case VIDEO_MODE_640x480_YUV411: ! vid->int_mode = MODE_640x480_YUV411; ! break; ! case VIDEO_MODE_640x480_RGB: ! vid->int_mode = MODE_640x480_RGB; ! break; ! default: ! printf("Sorry, Unsupported Video Format for IEEE1394 Camera.\n"); ! exit(1); ! } switch( vid->rate ) { case VIDEO_FRAME_RATE_1_875: --- 380,413 ---- } } ! if( initFlag == 0 ) { if( ar2Video1394Init(vid->debug, &vid->card, &vid->node) < 0 ) ! { ! fprintf (stderr, "Could not initialise 1394\n"); ! exit(1); ! } initFlag = 1; ! } ! ! switch( vid->mode ) ! { ! case VIDEO_MODE_320x240_YUV422: ! vid->int_mode = MODE_320x240_YUV422; ! break; ! case VIDEO_MODE_640x480_YUV411: ! vid->int_mode = MODE_640x480_YUV411; ! break; ! case VIDEO_MODE_640x480_RGB: ! vid->int_mode = MODE_640x480_RGB; ! break; ! default: ! printf("Sorry, Unsupported Video Format for IEEE1394 Camera.\n"); ! exit(1); ! break; ! } ! ! switch( vid->rate ) { case VIDEO_FRAME_RATE_1_875: *************** *** 356,360 **** exit(1); } ! /*-----------------------------------------------------------------------*/ /* report camera's features */ --- 433,441 ---- exit(1); } ! ! ! ! ! /*-----------------------------------------------------------------------*/ /* report camera's features */ *************** *** 368,372 **** dc1394_print_feature_set( &(vid->features) ); } ! /* Change the camera settings if we need to */ --- 449,453 ---- dc1394_print_feature_set( &(vid->features) ); } ! /* Change the camera settings if we need to */ *************** *** 383,389 **** ! /* Dump out the new parameters now */ ! if (vid->debug) ! dc1394_print_feature_set( &(vid->features) ); --- 464,470 ---- ! /* Dump out the new parameters now - this is only for code testing */ ! /* if (vid->debug) ! dc1394_print_feature_set( &(vid->features) ); */ *************** *** 392,396 **** /*-----------------------------------------------------------------------*/ if( dc1394_query_supported_formats(arV1394.handle, vid->node, &value) != DC1394_SUCCESS ) { ! fprintf( stderr, "unable to query_supported_formats\n"); } i = 31 - (FORMAT_VGA_NONCOMPRESSED - FORMAT_MIN); --- 473,477 ---- /*-----------------------------------------------------------------------*/ if( dc1394_query_supported_formats(arV1394.handle, vid->node, &value) != DC1394_SUCCESS ) { ! fprintf( stderr, "unable to query_supported_formats\n"); } i = 31 - (FORMAT_VGA_NONCOMPRESSED - FORMAT_MIN); *************** *** 401,413 **** exit(0); } dc1394_query_supported_modes(arV1394.handle, vid->node, FORMAT_VGA_NONCOMPRESSED, &value); i = 31 - (vid->int_mode - MODE_FORMAT0_MIN); p1 = 1 << i; p2 = value & p1; ! if( p2 == 0 ) { ! fprintf( stderr, "Unsupported Mode for the specified camera.\n"); ! ar2VideoDispOption(); ! exit(0); ! } dc1394_query_supported_framerates(arV1394.handle, vid->node, FORMAT_VGA_NONCOMPRESSED, vid->int_mode, &value); i = 31 - (vid->int_rate - FRAMERATE_MIN); --- 482,511 ---- exit(0); } + + /* Check that the camera supports the particular video mode we asked for */ dc1394_query_supported_modes(arV1394.handle, vid->node, FORMAT_VGA_NONCOMPRESSED, &value); i = 31 - (vid->int_mode - MODE_FORMAT0_MIN); p1 = 1 << i; p2 = value & p1; ! if( p2 == 0 ) ! { ! /* Test if the camera supports mono, if so then it is probably a dragonfly camera which uses mono but with Bayer encoding */ ! i = 31 - (MODE_640x480_MONO - MODE_FORMAT0_MIN); ! p1 = 1 << i; ! p2 = value & p1; ! if (p2 == 0) ! { ! fprintf( stderr, "Unsupported Mode for the specified camera.\n"); ! ar2VideoDispOption(); ! exit(0); ! } ! else ! { ! fprintf (stderr, "Detected a mono camera, assuming DragonFly camera with Bayer image decoding\n"); ! vid->int_mode = MODE_640x480_MONO; ! ar2Video_dragonfly = 1; ! } ! } ! dc1394_query_supported_framerates(arV1394.handle, vid->node, FORMAT_VGA_NONCOMPRESSED, vid->int_mode, &value); i = 31 - (vid->int_rate - FRAMERATE_MIN); *************** *** 419,427 **** exit(0); } ! /*-----------------------------------------------------------------------*/ /* setup capture */ /*-----------------------------------------------------------------------*/ - sprintf (video1394devname, "/dev/video1394/%d", vid->card); if( dc1394_dma_setup_capture(arV1394.handle, vid->node, --- 517,534 ---- exit(0); } ! ! ! /* Decide on where the video1394 device nodes are, they can be either at ! /dev/video1394/* or /dev/video1394-* depending on the distribution */ ! struct stat video_stat; ! if (stat ("/dev/video1394", &video_stat) < 0) ! sprintf (video1394devname, "/dev/video1394-%d", vid->card); ! else ! sprintf (video1394devname, "/dev/video1394/%d", vid->card); ! ! /*-----------------------------------------------------------------------*/ /* setup capture */ /*-----------------------------------------------------------------------*/ if( dc1394_dma_setup_capture(arV1394.handle, vid->node, *************** *** 439,443 **** 0, /* do_extra_buffering */ #endif ! #if !defined(LIBDC_8) || defined(LIBDC_11) 1, video1394devname, /* drop_frames, dma_device_file */ #endif --- 546,550 ---- 0, /* do_extra_buffering */ #endif ! #ifndef LIBDC_8 1, video1394devname, /* drop_frames, dma_device_file */ #endif *************** *** 449,453 **** "supported by your camera\n", __LINE__,__FILE__); ! exit(0); } --- 556,560 ---- "supported by your camera\n", __LINE__,__FILE__); ! exit(1); } *************** *** 456,462 **** fprintf( stderr, "unable to set camera trigger mode (ignored)\n"); } ! ! arMalloc( vid->image, ARUint8, (vid->camera.frame_width * vid->camera.frame_height * AR_PIX_SIZE_DEFAULT) ); ! return vid; } --- 563,569 ---- fprintf( stderr, "unable to set camera trigger mode (ignored)\n"); } ! ! arMalloc( vid->image, ARUint8, (vid->camera.frame_width * vid->camera.frame_height * AR_PIX_SIZE) ); ! return vid; } *************** *** 466,470 **** int i; ! if (vid->status == 1 || vid->status == 2) ar2VideoCapStop(vid); #if 0 --- 573,577 ---- int i; ! if( vid->status > 0 ) ar2VideoCapStop( vid ); #if 0 *************** *** 475,480 **** raw1394_destroy_handle(arV1394.handle); ! initFlag = 0; ! return 0; } --- 582,587 ---- raw1394_destroy_handle(arV1394.handle); ! initFlag = 0; ! return 0; } *************** *** 489,497 **** return -1; } ! /*-----------------------------------------------------------------------*/ /* setup capture */ /*-----------------------------------------------------------------------*/ ! sprintf (video1394devname, "/dev/video1394/%d", vid->card); if( vid->status == 3 ) { if( dc1394_dma_setup_capture(arV1394.handle, --- 596,608 ---- return -1; } ! /*-----------------------------------------------------------------------*/ /* setup capture */ /*-----------------------------------------------------------------------*/ ! struct stat video_stat; ! if (stat ("/dev/video1394", &video_stat) < 0) ! sprintf (video1394devname, "/dev/video1394-%d", vid->card); ! else ! sprintf (video1394devname, "/dev/video1394/%d", vid->card); if( vid->status == 3 ) { if( dc1394_dma_setup_capture(arV1394.handle, *************** *** 510,514 **** 0, /* do_extra_buffering */ #endif ! #if !defined(LIBDC_8) || defined(LIBDC_11) 1, video1394devname, /* drop_frames, dma_device_file */ #endif --- 621,625 ---- 0, /* do_extra_buffering */ #endif ! #ifndef LIBDC_8 1, video1394devname, /* drop_frames, dma_device_file */ #endif *************** *** 520,524 **** "supported by your camera\n", __LINE__,__FILE__); ! exit(0); } } --- 631,635 ---- "supported by your camera\n", __LINE__,__FILE__); ! exit(1); } } *************** *** 605,609 **** case MODE_640x480_RGB: return (ARUint8 *)vid->camera.capture_buffer; ! case MODE_640x480_YUV411: buf = vid->image; --- 716,789 ---- case MODE_640x480_RGB: return (ARUint8 *)vid->camera.capture_buffer; ! ! ! case MODE_640x480_MONO: ! { ! /* We only currently support Bayer image decoding from Point Grey cameras */ ! if (ar2Video_dragonfly < 0) ! { ! fprintf (stderr, "It is not possible to be in mono mode without the dragonfly flag being set previously\n"); ! exit (1); ! } ! ! /* If the image data is NULL then we should immediately return to avoid doing an image conversion which probably won't work! */ ! if (vid->camera.capture_buffer == NULL) ! return ((ARUint8 *)vid->camera.capture_buffer); ! ! /* This Bayer code was copied from LGPL'd code by Don Murray <do...@pt...>, and I then modified it to fix up a few things */ ! ! /* Query the camera to detect the Bayer pattern type */ ! quadlet_t qValue; ! GetCameraControlRegister (arV1394.handle, vid->node, 0x1040, &qValue); ! bayer_pattern_t pattern = BAYER_PATTERN_BGGR; ! static bayer_pattern_t prev_pattern = -1; ! switch( qValue ) ! { ! case 0x42474752: /* BGGR */ ! pattern = BAYER_PATTERN_BGGR; ! break; ! case 0x47524247: /* GRBG */ ! pattern = BAYER_PATTERN_GRBG; ! break; ! case 0x52474742: /* RGGB */ ! pattern = BAYER_PATTERN_RGGB; ! break; ! case 0x47425247: /* GBRG */ ! pattern = BAYER_PATTERN_GBRG; ! break; ! case 0x59595959: /* YYYY = BW */ ! printf ("Camera is black and white, Bayer conversion is not possible\n"); ! exit (1); ! default: ! if (prev_pattern == -1) ! { ! printf ("Camera BAYER_TILE_MAPPING register has an unexpected value 0x%x on initial startup, which should not occur\n", qValue); ! exit (1); ! } ! else ! { ! /* This is a wierd bug where occasionally you get an invalid register value and I have no idea why this is */ ! printf ("WARNING! The BAYER_TILE_MAPPING register has an unexpected value 0x%x, but I was able to use the previous stored result\n", qValue); ! pattern = prev_pattern; ! } ! } ! ! /* Store the previous Bayer pattern value */ ! prev_pattern = pattern; ! ! /* Do the Bayer image conversion now */ ! unsigned char *dest = vid->image; ! unsigned char *src = (ARUint8 *)vid->camera.capture_buffer; ! BayerNearestNeighbor( src, ! dest, ! vid->camera.frame_width, ! vid->camera.frame_height, ! pattern ); ! ! /* Image is done, we can now return it! */ ! return (vid->image); ! } ! ! case MODE_640x480_YUV411: buf = vid->image; *************** *** 738,742 **** ((*card != -1) && (*node == -1))) { ! fprintf (stderr, "Card value is %d and node value is %d, you must either auto-detect both or specify both\n"); exit (1); } --- 918,922 ---- ((*card != -1) && (*node == -1))) { ! fprintf (stderr, "Card value is %d and node value is %d, you must either auto-detect both or specify both\n", *card, *node); exit (1); } |