video.c
Go to the documentation of this file.
00001 /*
00002   1394 Linux Firewire Digital Camera Interface
00003   Copyright (c) 2002-2007
00004   Kiyoshi Kiyokawa (kiyo@crl.go.jp)
00005   Hirokazu Kato (kato@sys.im.hiroshima-cu.ac.jp)
00006   Wayne Piekarski (wayne@cs.unisa.edu.au)
00007   
00008   $Id: video.c,v 1.15 2007/01/23 00:39:28 philip_lamb Exp $
00009   This source file is dual licensed under either the GPL or the LGPL license
00010   by the authors of this software.
00011   
00012   --
00013   
00014   This program is free software; you can redistribute it and/or modify
00015   it under the terms of the GNU General Public License as published by
00016   the Free Software Foundation; either version 2 of the License, or
00017   (at your option) any later version.
00018 
00019   This program is distributed in the hope that it will be useful,
00020   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022   GNU General Public License for more details.
00023   
00024   You should have received a copy of the GNU General Public License
00025   along with this program; if not, write to the Free Software
00026   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027   
00028   --
00029   
00030   This library is free software; you can redistribute it and/or
00031   modify it under the terms of the GNU Lesser General Public
00032   License as published by the Free Software Foundation; either
00033   version 2.1 of the License, or (at your option) any later version.
00034   
00035   This library is distributed in the hope that it will be useful,
00036   but WITHOUT ANY WARRANTY; without even the implied warranty of
00037   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00038   Lesser General Public License for more details.
00039   
00040   You should have received a copy of the GNU Lesser General Public
00041   License along with this library; if not, write to the Free Software
00042   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
00043 
00044   
00045 /* 
00046  *   Revision: 1.0   Date: 2002/01/01
00047  *   Video capture subrutine for Linux/libdc1394 devices
00048  *   author: Kiyoshi Kiyokawa ( kiyo@crl.go.jp )
00049  *           Hirokazu Kato ( kato@sys.im.hiroshima-cu.ac.jp )
00050  *
00051  *
00052  *   Revision: 1.1   Date: 2004/09/30
00053  *   Modifications by Wayne Piekarski ( wayne@cs.unisa.edu.au )
00054  *   - #ifdef macros added to support the many different versions of libdc1394
00055  *   - Initialisation code rewritten to support multiple 1394 busses
00056  *   - Either autodetect of cameras or specifying the exact camera is now possible
00057  *   - Support for changing of various 1394 camera properties
00058  *
00059  *
00060  *   Revision 1.1.1  Date: 2005/03/14
00061  *   - Patch by Henrik Erkkonen to support version 11 of libdc1394.
00062  *   - (Removed in later 1.3 changes by Wayne)
00063  *
00064  *
00065  *   Revision: 1.2   Date: 2005/07/20
00066  *   Modifications by Wayne Piekarski ( wayne@cs.unisa.edu.au )
00067  *   - Added support for Bayer image tiling for Point Grey DragonFly cameras
00068  *
00069  *
00070  *   Revision: 1.3   Date: 2006/09/16 ( wayne@cs.unisa.edu.au )
00071  *   - Stabilised interfaces around latest libdc1394 libraries
00072  *   - Added various other cleanups and bug fixes to make the code more stable
00073  *   - Added licensing allowing LGPL or existing GPL with permission from original authors
00074  *   - Rearranged various constants from AR/config.h to make things easier to understand
00075  *   - Better config string support with ARTOOLKIT_CONFIG to override defaults from the shell
00076  *
00077  */
00078 
00079 #include <sys/ioctl.h>
00080 #include <sys/types.h>
00081 #include <sys/stat.h>
00082 #include <sys/mman.h>
00083 #include <fcntl.h>
00084 #include <unistd.h>
00085 #include <stdio.h>
00086 #include <stdlib.h>
00087 #include <string.h>
00088 #include <linux/types.h>
00089 #include <libraw1394/raw1394.h>
00090 #include <libdc1394/dc1394_control.h>
00091 #include <AR/config.h>
00092 #include <AR/ar.h>
00093 #include <AR/video.h>
00094 
00095 
00096 
00097 
00098 /* Do not touch the following macros! */
00099 #undef  LIBDC_8
00100 #undef  LIBDC_9
00101 #undef  LIBDC_10
00102 #undef  LIBDC_11
00103 #undef  LIBDC_DEF
00104 
00105 
00106 /* ----------------------- MAKE ANY #define CHANGES HERE ONLY -------------------------------- */
00107 /* This define controls if we use the new or old libDC1394 API functions. In the past there were
00108    many development releases, but the latest 1.0.0 release is stable and modern Linux distributions
00109    have all standardised on this, so there is no need to make changes here any more. */
00110 // #define LIBDC_8
00111 // #define LIBDC_9
00112 // #define LIBDC_10
00113 #define LIBDC_11
00114 /* ----------------------- MAKE ANY #define CHANGES HERE ONLY -------------------------------- */
00115 
00116 
00117 /* These are some extra constants I defined for my modifications */
00118 #define DEFAULT_VIDEO_CARD -1
00119 #define MAX_PORTS 4 /* This is the maximum number of Firewire cards we can have installed in the system, it is an arbitrary number */
00120 
00121 
00122 
00123 
00124 /* Defines that control various aspects of this code */
00125 #define   VIDEO_NODE_ANY                      -1
00126 #define   VIDEO_MODE_320x240_YUV422           32
00127 #define   VIDEO_MODE_640x480_YUV411           33
00128 #define   VIDEO_MODE_640x480_RGB              34
00129 #define   VIDEO_MODE_640x480_YUV411_HALF      35
00130 #define   VIDEO_MODE_640x480_MONO             36
00131 #define   VIDEO_MODE_640x480_MONO_COLOR       37
00132 #define   VIDEO_MODE_640x480_MONO_COLOR_HALF  38
00133 #define   VIDEO_FRAME_RATE_1_875               1
00134 #define   VIDEO_FRAME_RATE_3_75                2
00135 #define   VIDEO_FRAME_RATE_7_5                 3
00136 #define   VIDEO_FRAME_RATE_15                  4
00137 #define   VIDEO_FRAME_RATE_30                  5
00138 #define   VIDEO_FRAME_RATE_60                  6
00139 #define   DEFAULT_VIDEO_NODE                   VIDEO_NODE_ANY
00140 #define   DEFAULT_VIDEO_MODE                   VIDEO_MODE_640x480_YUV411_HALF
00141 #define   DEFAULT_VIDEO_FRAME_RATE             VIDEO_FRAME_RATE_30
00142 
00143 
00144 
00145 
00146 /* Error checking to ensure we have a proper configuration, and put some debugging out */
00147 #ifdef LIBDC_8
00148 #warning Compiling using original 0.8.3 libDC library (single camera only) - debian: libdc1394-8-dev
00149 #warning The 0.8.3 libDC code is dangerous and has a number of bugs which will cause trouble - upgrade to 0.9.1 or later!
00150 #define LIBDC_DEF
00151 #endif
00152 
00153 #ifdef LIBDC_9
00154 #warning Compiling using an older 0.9.1 libDC library (multiple camera support) - debian: libdc1394-9-dev
00155 #define LIBDC_DEF
00156 #endif
00157 
00158 #ifdef LIBDC_10
00159 #warning Compiling using an older 0.9.5 libDC library (multiple camera support) - debian: libdc1394-10-dev
00160 #define LIBDC_DEF
00161 #endif
00162 
00163 #ifdef LIBDC_11
00164 // #warning Compiling using the stable 1.0.0 libDC library (multiple camera support) - debian: libdc1394-11-dev
00165 #define LIBDC_DEF
00166 #endif
00167 
00168 #ifndef LIBDC_DEF
00169 #error One of the LIBDC_[8,9,10,11] macros must be defined to compile this code properly!
00170 #endif
00171 
00172 
00173 
00174 
00175 /* Here are some extra definitions to support Point Grey DragonFly cameras */
00176 #include "conversions.h"
00177 int ar2Video_dragonfly = -1;
00178 
00179 
00180 
00181 
00182 static AR2VideoParamT   *gVid = NULL;
00183 
00184 int arVideoDispOption( void )
00185 {
00186     return  ar2VideoDispOption();
00187 }
00188 
00189 int arVideoOpen( char *config )
00190 {
00191     if( gVid != NULL ) {
00192       fprintf(stderr, "The device has already been opened!\n");
00193       exit (1);
00194     }
00195     gVid = ar2VideoOpen( config );
00196     if (gVid == NULL)
00197       return (-1);
00198     
00199     return 0;
00200 }
00201 
00202 int arVideoClose( void )
00203 {
00204   int result;
00205   
00206   if( gVid == NULL ) return -1;
00207   
00208   result = ar2VideoClose(gVid);
00209   gVid = NULL;
00210   return (result);
00211 }
00212 
00213 int arVideoInqSize( int *x, int *y )
00214 {
00215     if( gVid == NULL ) return -1;
00216 
00217     return ar2VideoInqSize( gVid, x, y );
00218 }
00219 
00220 ARUint8 *arVideoGetImage( void )
00221 {
00222     if( gVid == NULL ) return NULL;
00223 
00224     return ar2VideoGetImage( gVid );
00225 }
00226 
00227 int arVideoCapStart( void )
00228 {
00229     if( gVid == NULL ) return -1;
00230 
00231     return ar2VideoCapStart( gVid );
00232 }
00233 
00234 int arVideoCapStop( void )
00235 {
00236     if( gVid == NULL ) return -1;
00237 
00238     return ar2VideoCapStop( gVid );
00239 }
00240 
00241 int arVideoCapNext( void )
00242 {
00243     if( gVid == NULL ) return -1;
00244 
00245     return ar2VideoCapNext( gVid );
00246 }
00247 
00248 /*-------------------------------------------*/
00249 
00250 
00251 typedef struct __arVideo1394
00252 {
00253     raw1394handle_t         handle;
00254 } ARVideo1394;
00255 
00256 static ARVideo1394   arV1394;
00257 static int           initFlag = 0;
00258 
00259 static int ar2Video1394Init( int debug, int *card, int *node );
00260 
00261 
00262 int ar2VideoDispOption( void )
00263 {
00264     printf ("\n");
00265     printf("ARVideo may be configured using one or more of the following options, separated by a space:\n\n");
00266     printf(" -node=N\n");
00267     printf("    specifies detected node ID of a FireWire camera (-1: Any).\n");
00268     printf(" -card=N\n");
00269     printf("    specifies the FireWire adaptor id number (-1: Any).\n");
00270     printf(" -mode=[320x240_YUV422|640x480_RGB|640x480_YUV411]\n");
00271     printf("    specifies input image format.\n");
00272     printf(" -rate=N\n");
00273     printf("    specifies desired framerate of a FireWire camera. \n");
00274     printf("    (1.875, 3.75, 7.5, 15, 30, 60)\n");
00275     printf(" -[name]=N  where name is brightness, iris, shutter, gain, saturation, gamma, sharpness\n");
00276     printf("    (value must be a legal value for this parameter - use coriander to find what they are\n");
00277     printf("\n");
00278     printf(" Note that if no config string is supplied, you can override it with the environment variable ARTOOLKIT_CONFIG\n");
00279     printf("\n");
00280     
00281     return 0;
00282 }
00283 
00284 AR2VideoParamT *ar2VideoOpen( char *config_in )
00285 {
00286     char                      video1394devname [128];
00287     AR2VideoParamT            *vid;
00288     ARUint32                  p1,p2;
00289     quadlet_t                 value;
00290     char                      *config, *a, line[256];
00291     int                       i;
00292     
00293     int brightness = -1;
00294     int iris = -1;
00295     int shutter = -1;
00296     int gain = -1;
00297     int saturation = -1;
00298     int gamma = -1;
00299     int sharpness = -1;
00300     
00301     arMalloc( vid, AR2VideoParamT, 1 );
00302     vid->node         = DEFAULT_VIDEO_NODE;
00303     vid->card         = DEFAULT_VIDEO_CARD;
00304     vid->mode         = DEFAULT_VIDEO_MODE;
00305     vid->rate         = DEFAULT_VIDEO_FRAME_RATE;
00306     vid->channel      = 0;
00307     vid->speed        = SPEED_400;
00308     vid->format       = FORMAT_VGA_NONCOMPRESSED;
00309     vid->dma_buf_num  = 16;
00310     vid->debug        = 0;
00311     vid->status       = 0;
00312     
00313         /* If no config string is supplied, we should use the environment variable, otherwise set a sane default */
00314         if (!config_in || !(config_in[0])) {
00315                 /* None suppplied, lets see if the user supplied one from the shell */
00316                 char *envconf = getenv ("ARTOOLKIT_CONFIG");
00317                 if (envconf && envconf[0]) {
00318                         config = envconf;
00319                         printf ("Using config string from environment [%s].\n", envconf);
00320                 } else {
00321                         config = NULL;
00322                         printf ("No video config string supplied, using defaults.\n");
00323                 }
00324         } else {
00325                 config = config_in;
00326                 printf ("Using supplied video config string [%s].\n", config_in);
00327         }
00328 
00329         a = config;
00330     if( a != NULL) {
00331         for(;;) {
00332             while( *a == ' ' || *a == '\t' ) a++;
00333             if( *a == '\0' ) break;
00334 
00335             if( strncmp( a, "-mode=", 6 ) == 0 ) {
00336                 if ( strncmp( &a[6], "320x240_YUV422", 14 ) == 0 ) {
00337                     vid->mode = VIDEO_MODE_320x240_YUV422;
00338                 }
00339                 else if ( strncmp( &a[6], "640x480_YUV411", 14 ) == 0 ) {
00340                     vid->mode = VIDEO_MODE_640x480_YUV411;
00341                 }
00342                 else if ( strncmp( &a[6], "640x480_RGB", 11 ) == 0 ) {
00343                     vid->mode = VIDEO_MODE_640x480_RGB;
00344                 }
00345                 else {
00346                     ar2VideoDispOption();
00347                     free( vid );
00348                     return 0;
00349                 }
00350             }
00351             
00352             else if( strncmp( a, "-iris=", 6 ) == 0 ) {
00353                 sscanf( a, "%s", line );
00354                 if( sscanf( &line[6], "%d", &iris ) == 0 ) {
00355                     ar2VideoDispOption();
00356                     free( vid );
00357                     return 0;
00358                 }
00359             }
00360             else if( strncmp( a, "-gain=", 6 ) == 0 ) {
00361                 sscanf( a, "%s", line );
00362                 if( sscanf( &line[6], "%d", &gain ) == 0 ) {
00363                     ar2VideoDispOption();
00364                     free( vid );
00365                     return 0;
00366                 }
00367             }
00368             
00369             else if( strncmp( a, "-node=", 6 ) == 0 ) {
00370                 sscanf( a, "%s", line );
00371                 if( sscanf( &line[6], "%d", &vid->node ) == 0 ) {
00372                     ar2VideoDispOption();
00373                     free( vid );
00374                     return 0;
00375                 }
00376             }
00377             else if( strncmp( a, "-card=", 6 ) == 0 ) {
00378                 sscanf( a, "%s", line );
00379                 if( sscanf( &line[6], "%d", &vid->card ) == 0 ) {
00380                     ar2VideoDispOption();
00381                     free( vid );
00382                     return 0;
00383                 }
00384             }
00385             else if( strncmp( a, "-rate=", 6 ) == 0 ) {
00386                 if ( strncmp( &a[6], "1.875", 5 ) == 0 ) {
00387                     vid->rate = VIDEO_FRAME_RATE_1_875;
00388                 }
00389                 else if ( strncmp( &a[6], "3.75", 4 ) == 0 ) {
00390                     vid->rate = VIDEO_FRAME_RATE_3_75;
00391                 }
00392                 else if ( strncmp( &a[6], "7.5", 3 ) == 0 ) {
00393                     vid->rate = VIDEO_FRAME_RATE_7_5;
00394                 }
00395                 else if ( strncmp( &a[6], "15", 2 ) == 0 ) {
00396                     vid->rate = VIDEO_FRAME_RATE_15;
00397                 }
00398                 else if ( strncmp( &a[6], "30", 2 ) == 0 ) {
00399                     vid->rate = VIDEO_FRAME_RATE_30;
00400                 }
00401                 else if ( strncmp( &a[6], "60", 2 ) == 0 ) {
00402                     vid->rate = VIDEO_FRAME_RATE_60;
00403                 }
00404                 else {
00405                     ar2VideoDispOption();
00406                     free( vid );
00407                     return 0;
00408                 }
00409             }
00410             else if( strncmp( a, "-debug", 6 ) == 0 ) {
00411                 vid->debug = 1;
00412             }
00413             else if( strncmp( a, "-adjust", 7 ) == 0 ) {
00414               /* Do nothing - this is for V4L compatibility */
00415             }
00416             else {
00417                 ar2VideoDispOption();
00418                 free( vid );
00419                 return 0;
00420             }
00421 
00422             while( *a != ' ' && *a != '\t' && *a != '\0') a++;
00423         }
00424     }
00425     
00426     
00427     if( initFlag == 0 )
00428       {
00429         if( ar2Video1394Init(vid->debug, &vid->card, &vid->node) < 0 )
00430           {
00431             fprintf (stderr, "Could not initialise 1394\n");
00432             exit(1);
00433           }
00434         initFlag = 1;
00435       }
00436     
00437     switch( vid->mode )
00438       {
00439       case VIDEO_MODE_320x240_YUV422:
00440         vid->int_mode = MODE_320x240_YUV422;
00441         break;
00442       case VIDEO_MODE_640x480_YUV411:
00443         vid->int_mode = MODE_640x480_YUV411;
00444         break;
00445       case VIDEO_MODE_640x480_RGB:
00446         vid->int_mode = MODE_640x480_RGB;
00447         break;
00448       default:
00449         printf("Sorry, Unsupported Video Format for IEEE1394 Camera.\n");
00450         exit(1);
00451         break;
00452       }
00453     
00454     
00455     switch( vid->rate ) {
00456         case VIDEO_FRAME_RATE_1_875:
00457           vid->int_rate = FRAMERATE_1_875;
00458           break;
00459         case VIDEO_FRAME_RATE_3_75:
00460           vid->int_rate = FRAMERATE_3_75;
00461           break;
00462         case VIDEO_FRAME_RATE_7_5:
00463           vid->int_rate = FRAMERATE_7_5;
00464           break;
00465         case VIDEO_FRAME_RATE_15:
00466           vid->int_rate = FRAMERATE_15;
00467           break;
00468         case VIDEO_FRAME_RATE_30:
00469           vid->int_rate = FRAMERATE_30;
00470           break;
00471         case VIDEO_FRAME_RATE_60:
00472           vid->int_rate = FRAMERATE_60;
00473           break;
00474         default:
00475           fprintf(stderr, "Sorry, Unsupported Frame Rate for IEEE1394 Camera.\n");
00476           exit(1);
00477     }
00478     
00479 
00480     
00481     
00482     
00483     /*-----------------------------------------------------------------------*/
00484     /*  report camera's features                                             */
00485     /*-----------------------------------------------------------------------*/
00486     if( dc1394_get_camera_feature_set(arV1394.handle, 
00487                                       vid->node,
00488                                       &(vid->features)) != DC1394_SUCCESS ) {
00489         fprintf( stderr, "unable to get feature set\n");
00490     }
00491     else if( vid->debug ) {
00492       dc1394_print_feature_set( &(vid->features) );
00493     }
00494     
00495     
00496     /* Change the camera settings if we need to */
00497     if (iris != -1)
00498       {
00499         fprintf (stderr, "Adjusting IRIS setting to %d\n", iris);
00500         dc1394_set_iris (arV1394.handle, vid->node, (unsigned int)iris);
00501       }
00502     if (gain != -1)
00503       {
00504         fprintf (stderr, "Adjusting GAIN setting to %d\n", gain);
00505         dc1394_set_gain (arV1394.handle, vid->node, (unsigned int)gain);
00506       }
00507     
00508     
00509     /* Dump out the new parameters now - this is only for code testing */
00510     /* if (vid->debug)
00511        dc1394_print_feature_set( &(vid->features) ); */
00512     
00513     
00514     /*-----------------------------------------------------------------------*/
00515     /*  check parameters                                                     */
00516     /*-----------------------------------------------------------------------*/
00517     if( dc1394_query_supported_formats(arV1394.handle, vid->node, &value) != DC1394_SUCCESS ) {
00518       fprintf( stderr, "unable to query_supported_formats\n");
00519     }
00520     i = 31 - (FORMAT_VGA_NONCOMPRESSED - FORMAT_MIN);
00521     p1 = 1 << i;
00522     p2 = value & p1;
00523     if( p2 == 0 ) {
00524         fprintf( stderr, "unable to use this camera on VGA_NONCOMPRESSED format.\n");
00525         exit(0);
00526     }
00527     
00528     /* Check that the camera supports the particular video mode we asked for */
00529     dc1394_query_supported_modes(arV1394.handle, vid->node,  FORMAT_VGA_NONCOMPRESSED, &value);
00530     i = 31 - (vid->int_mode - MODE_FORMAT0_MIN);
00531     p1 = 1 << i;
00532     p2 = value & p1;
00533     if( p2 == 0 )
00534       {
00535         /* Test if the camera supports mono, if so then it is probably a dragonfly camera which uses mono but with Bayer encoding */
00536         i = 31 - (MODE_640x480_MONO - MODE_FORMAT0_MIN);
00537         p1 = 1 << i;
00538         p2 = value & p1;
00539         if (p2 == 0)
00540           {
00541             fprintf( stderr, "Unsupported Mode for the specified camera.\n");
00542             ar2VideoDispOption();
00543             exit(0);
00544           }
00545         else
00546           {
00547             fprintf (stderr, "Detected a mono camera, assuming DragonFly camera with Bayer image decoding\n");
00548             vid->int_mode = MODE_640x480_MONO;
00549             ar2Video_dragonfly = 1;
00550           }
00551       }
00552     
00553     dc1394_query_supported_framerates(arV1394.handle, vid->node, FORMAT_VGA_NONCOMPRESSED, vid->int_mode, &value);
00554     i = 31 - (vid->int_rate - FRAMERATE_MIN);
00555     p1 = 1 << i;
00556     p2 = value & p1;
00557     if( p2 == 0 ) {
00558         fprintf( stderr, "Unsupported Framerate for the specified mode.\n");
00559         ar2VideoDispOption();
00560         exit(0);
00561     }
00562     
00563     
00564     /* Decide on where the video1394 device nodes are, they can be either at
00565        /dev/video1394/ or /dev/video1394-* depending on the distribution */
00566     struct stat video_stat;
00567     if (stat ("/dev/video1394", &video_stat) < 0)
00568       sprintf (video1394devname, "/dev/video1394-%d", vid->card);
00569     else
00570       sprintf (video1394devname, "/dev/video1394/%d", vid->card);
00571     
00572     
00573     /*-----------------------------------------------------------------------*/
00574     /*  setup capture                                                        */
00575     /*-----------------------------------------------------------------------*/
00576     if( dc1394_dma_setup_capture(arV1394.handle,
00577                                  vid->node,
00578 #ifndef LIBDC_8
00579                                  vid->node,
00580 #else
00581                                  vid->channel,
00582 #endif
00583                                  vid->format,
00584                                  vid->int_mode,
00585                                  vid->speed,
00586                                  vid->int_rate,
00587                                  vid->dma_buf_num,
00588 #ifdef LIBDC_10
00589                                  0, /* do_extra_buffering */
00590 #endif
00591 #ifndef LIBDC_8
00592                                  1, video1394devname, /* drop_frames, dma_device_file */
00593 #endif
00594                                  &(vid->camera)) != DC1394_SUCCESS ) {
00595         fprintf( stderr,"unable to setup camera-\n"
00596                 "check if you did 'insmod video1394' or,\n"
00597                 "check line %d of %s to make sure\n"
00598                 "that the video mode,framerate and format are\n"
00599                 "supported by your camera\n",
00600                 __LINE__,__FILE__);
00601         exit(1);
00602     }
00603   
00604     /* set trigger mode */
00605     if( dc1394_set_trigger_mode(arV1394.handle, vid->node, TRIGGER_MODE_0) != DC1394_SUCCESS ) {
00606         fprintf( stderr, "unable to set camera trigger mode (ignored)\n");
00607     }
00608     
00609     arMalloc( vid->image, ARUint8, (vid->camera.frame_width * vid->camera.frame_height * AR_PIX_SIZE_DEFAULT) );
00610     
00611     return vid;
00612 }
00613 
00614 int ar2VideoClose( AR2VideoParamT *vid )
00615 {
00616     int     i;
00617 
00618     if( vid->status > 0 ) ar2VideoCapStop( vid );
00619 
00620 #if 0
00621     dc1394_dma_release_camera(arV1394.handle, &(vid->camera));
00622 #endif
00623     free( vid->image );
00624     free( vid );
00625     
00626     raw1394_destroy_handle(arV1394.handle);
00627     initFlag = 0;
00628     
00629     return 0;
00630 } 
00631 
00632 int ar2VideoCapStart( AR2VideoParamT *vid )
00633 {
00634     char video1394devname [128];
00635     
00636     
00637     if(vid->status != 0 && vid->status != 3){
00638         fprintf(stderr, "arVideoCapStart has already been called.\n");
00639         return -1;
00640     }
00641     
00642     /*-----------------------------------------------------------------------*/
00643     /*  setup capture                                                        */
00644     /*-----------------------------------------------------------------------*/
00645     struct stat video_stat;
00646     if (stat ("/dev/video1394", &video_stat) < 0)
00647       sprintf (video1394devname, "/dev/video1394-%d", vid->card);
00648     else
00649       sprintf (video1394devname, "/dev/video1394/%d", vid->card);
00650     if( vid->status == 3 ) {
00651         if( dc1394_dma_setup_capture(arV1394.handle,
00652                                      vid->node,
00653 #ifndef LIBDC_8
00654                                      vid->node,
00655 #else
00656                                      vid->channel,
00657 #endif
00658                                      vid->format,
00659                                      vid->int_mode,
00660                                      vid->speed,
00661                                      vid->int_rate,
00662                                      vid->dma_buf_num,
00663 #ifdef LIBDC_10
00664                                      0, /* do_extra_buffering */
00665 #endif
00666 #ifndef LIBDC_8
00667                                      1, video1394devname, /* drop_frames, dma_device_file */
00668 #endif
00669                                      &(vid->camera)) != DC1394_SUCCESS ) {
00670             fprintf( stderr,"unable to setup camera-\n"
00671                     "check if you did 'insmod video1394' or,\n"
00672                     "check line %d of %s to make sure\n"
00673                     "that the video mode,framerate and format are\n"
00674                     "supported by your camera\n",
00675                     __LINE__,__FILE__);
00676             exit(1);
00677         }
00678     }
00679 
00680     if( dc1394_start_iso_transmission(arV1394.handle, vid->node) != DC1394_SUCCESS ) {
00681         fprintf( stderr, "unable to start camera iso transmission\n");
00682         return -1;
00683     }
00684 
00685     vid->status = 1;
00686 
00687     return 0;
00688 }
00689 
00690 int ar2VideoCapNext( AR2VideoParamT *vid )
00691 {
00692     if(vid->status == 0 || vid->status == 3){
00693         fprintf(stderr, "arVideoCapStart has never been called.\n");
00694         return -1;
00695     }
00696     if(vid->status == 2) vid->status = 1;
00697 
00698     dc1394_dma_done_with_buffer( &(vid->camera) );
00699 
00700     return 0;
00701 }
00702 
00703 int ar2VideoCapStop( AR2VideoParamT *vid )
00704 {
00705     if(vid->status == 2){
00706         if( dc1394_dma_single_capture( &(vid->camera) ) != DC1394_SUCCESS ) {
00707             fprintf( stderr, "unable to capture a frame\n");
00708         }
00709     }
00710     if(vid->status == 0){
00711         fprintf(stderr, "arVideoCapStart has never been called.\n");
00712         return -1;
00713     }
00714     vid->status = 3;
00715 
00716     if( dc1394_stop_iso_transmission(arV1394.handle, vid->node) != DC1394_SUCCESS ) {
00717         fprintf(stderr, "couldn't stop the camera?\n");
00718         return -1;
00719     }
00720 
00721     dc1394_dma_release_camera(arV1394.handle, &(vid->camera));
00722 
00723     return 0;
00724 }
00725 
00726 int ar2VideoInqSize(AR2VideoParamT *vid, int *x,int *y)
00727 {
00728     *x = vid->camera.frame_width;
00729     *y = vid->camera.frame_height;
00730 
00731     return 0;
00732 }
00733 
00734 ARUint8 *ar2VideoGetImage( AR2VideoParamT *vid )
00735 {
00736     register ARUint8 *buf, *buf2;
00737     register int i, j;
00738     register int U, V, R, G, B, V2, U5, UV;
00739     register int Y0, Y1, Y2, Y3;
00740     register ARUint8 r, g, b;
00741 
00742     if(vid->status == 0){
00743         fprintf(stderr, "arVideoCapStart has never been called.\n");
00744         return NULL;
00745     }
00746     if(vid->status == 2){
00747         fprintf(stderr, "arVideoCapNext has never been called since previous arVideoGetImage.\n");
00748         return NULL;
00749     }
00750 
00751     if( dc1394_dma_single_capture( &(vid->camera) ) != DC1394_SUCCESS ) {
00752         fprintf(stderr, "unable to capture a frame\n");
00753         return NULL;
00754     }
00755     vid->status = 2;
00756 
00757 
00758     switch( vid->int_mode ) {
00759         case MODE_640x480_RGB:
00760           return (ARUint8 *)vid->camera.capture_buffer;
00761           
00762           
00763         case MODE_640x480_MONO:
00764           {
00765             /* We only currently support Bayer image decoding from Point Grey cameras */
00766             if (ar2Video_dragonfly < 0)
00767               {
00768                 fprintf (stderr, "It is not possible to be in mono mode without the dragonfly flag being set previously\n");
00769                 exit (1);
00770               }
00771             
00772             /* If the image data is NULL then we should immediately return to avoid doing an image conversion which probably won't work! */
00773             if (vid->camera.capture_buffer == NULL)
00774               return ((ARUint8 *)vid->camera.capture_buffer);
00775             
00776             /* This Bayer code was copied from LGPL'd code by Don Murray <donm@ptgrey.com>, and I then modified it to fix up a few things */
00777             
00778             /* Query the camera to detect the Bayer pattern type */
00779             quadlet_t qValue;
00780             GetCameraControlRegister (arV1394.handle, vid->node, 0x1040, &qValue);
00781             bayer_pattern_t pattern = BAYER_PATTERN_BGGR;
00782             static bayer_pattern_t prev_pattern = -1;
00783             switch( qValue )
00784               {
00785               case 0x42474752:  /* BGGR */
00786                 pattern = BAYER_PATTERN_BGGR;
00787                 break;
00788               case 0x47524247:  /* GRBG */
00789                 pattern = BAYER_PATTERN_GRBG;
00790                 break;
00791               case 0x52474742:  /* RGGB */
00792                 pattern = BAYER_PATTERN_RGGB;
00793                 break;
00794               case 0x47425247:  /* GBRG */
00795                 pattern = BAYER_PATTERN_GBRG;
00796                 break;
00797               case 0x59595959:  /* YYYY = BW */
00798                 fprintf (stderr, "Camera is black and white, Bayer conversion is not possible\n");
00799                 exit (1);
00800               default:
00801                 if (prev_pattern == -1)
00802                   {
00803                     fprintf (stderr, "Camera BAYER_TILE_MAPPING register has an unexpected value 0x%x on initial startup, which should not occur\n", qValue);
00804                     exit (1);
00805                   }
00806                 else
00807                   {
00808                     /* This is a wierd bug where occasionally you get an invalid register value and I have no idea why this is */
00809                     fprintf (stderr, "WARNING! The BAYER_TILE_MAPPING register has an unexpected value 0x%x, but I was able to use the previous stored result\n", qValue);
00810                     pattern = prev_pattern;
00811                   }
00812               }
00813             
00814             /* Store the previous Bayer pattern value */
00815             prev_pattern = pattern;
00816             
00817             /* Do the Bayer image conversion now */
00818             unsigned char *dest  = vid->image;
00819             unsigned char *src = (ARUint8 *)vid->camera.capture_buffer;
00820             BayerNearestNeighbor( src, 
00821                             dest,
00822                             vid->camera.frame_width,
00823                             vid->camera.frame_height,
00824                             pattern );
00825             
00826             /* Image is done, we can now return it! */
00827             return (vid->image);                
00828           }
00829           
00830           
00831         case MODE_640x480_YUV411:
00832           buf  = vid->image;
00833           buf2 = (ARUint8 *)vid->camera.capture_buffer;
00834           for( i = vid->camera.frame_height * vid->camera.frame_width / 4; i; i--) {
00835               U   = ((ARUint8)*buf2++ - 128) * 0.354;
00836               U5  = 5*U;
00837               Y0  = (ARUint8)*buf2++;
00838               Y1  = (ARUint8)*buf2++;
00839               V   = ((ARUint8)*buf2++ - 128) * 0.707;
00840               V2  = 2*V;
00841               Y2  = (ARUint8)*buf2++;
00842               Y3  = (ARUint8)*buf2++;
00843               UV  = - U - V;
00844 
00845               // Original equations
00846               // R = Y           + 1.402 V
00847               // G = Y - 0.344 U - 0.714 V
00848               // B = Y + 1.772 U
00849               R = Y0 + V2;
00850               if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
00851 
00852               G = Y0 + UV;
00853               if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
00854 
00855               B = Y0 + U5;
00856               if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
00857      
00858               *buf++ = (ARUint8)R;
00859               *buf++ = (ARUint8)G;
00860               *buf++ = (ARUint8)B;
00861 
00862               //---
00863               R = Y1 + V2;
00864               if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
00865 
00866               G = Y1 + UV;
00867               if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
00868 
00869               B = Y1 + U5;
00870               if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
00871      
00872               *buf++ = (ARUint8)R;
00873               *buf++ = (ARUint8)G;
00874               *buf++ = (ARUint8)B;
00875 
00876               //---
00877               R = Y2 + V2;
00878               if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
00879 
00880               G = Y2 + UV;
00881               if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
00882 
00883               B = Y2 + U5;
00884               if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
00885      
00886               *buf++ = (ARUint8)R;
00887               *buf++ = (ARUint8)G;
00888               *buf++ = (ARUint8)B;
00889 
00890               //---
00891               R = Y3 + V2;
00892               if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
00893 
00894               G = Y3 + UV;
00895               if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
00896 
00897               B = Y3 + U5;
00898               if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
00899      
00900               *buf++ = (ARUint8)R;
00901               *buf++ = (ARUint8)G;
00902               *buf++ = (ARUint8)B;
00903           }
00904           return vid->image;
00905 
00906         case MODE_320x240_YUV422:
00907           buf  = vid->image;
00908           buf2 = (ARUint8 *)vid->camera.capture_buffer;
00909           for( i = vid->camera.frame_height * vid->camera.frame_width / 2; i; i-- ) {
00910               U   = ((ARUint8)*buf2++ - 128) * 0.354;
00911               U5  = 5*U;
00912               Y0  = (ARUint8)*buf2++;
00913               V   = ((ARUint8)*buf2++ - 128) * 0.707;
00914               V2  = 2*V;
00915               Y1  = (ARUint8)*buf2++;
00916               UV  = - U - V;
00917 
00918               //---
00919               R = Y0 + V2;
00920               if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
00921 
00922               G = Y0 + UV;
00923               if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
00924 
00925               B = Y0 + U5;
00926               if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
00927       
00928               *buf++ = (ARUint8)R;
00929               *buf++ = (ARUint8)G;
00930               *buf++ = (ARUint8)B;
00931 
00932               //---
00933               R = Y1 + V2;
00934               if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
00935 
00936               G = Y1 + UV;
00937               if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
00938 
00939               B = Y1 + U5;
00940               if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
00941       
00942               *buf++ = (ARUint8)R;
00943               *buf++ = (ARUint8)G;
00944               *buf++ = (ARUint8)B;
00945           }
00946           return vid->image;
00947     }
00948 
00949     return NULL;
00950 }
00951 
00952 
00953 
00954 
00955 static int ar2Video1394Init( int debug, int *card, int *node )
00956 {
00957     int     i;
00958     
00959     /* The user must either specify both card and node, or neither of them */
00960     if (((*card == -1) && (*node != -1)) ||
00961         ((*card != -1) && (*node == -1)))
00962       {
00963         fprintf (stderr, "Card value is %d and node value is %d, you must either auto-detect both or specify both\n", *card, *node);
00964         exit (1);
00965       }
00966     
00967     /* If the user has specified so, we will autodetect for the camera and grab the first one we can find */
00968     if ((*card == -1) && (*node == -1))
00969       {
00970         /* Find the total number of firewire cards in the system */
00971         int numPorts = MAX_PORTS;
00972         int p;
00973         struct raw1394_portinfo ports[MAX_PORTS];
00974         raw1394handle_t raw_handle = raw1394_new_handle ();
00975         if (raw_handle == NULL)
00976           {
00977             fprintf (stderr, "Could not acquire a raw1394 handle - driver not installed?\n");
00978             exit (1);
00979           }
00980         numPorts = raw1394_get_port_info (raw_handle, ports, numPorts);
00981         raw1394_destroy_handle (raw_handle);
00982         
00983         /* Perform autodetection */
00984         printf ("Auto-detecting firewire camera because card and node is not specified\n");
00985         
00986         /* We need to traverse all available cards and process each one */
00987         for (p = 0; p < numPorts; p++)
00988           {
00989             /* Open up OHCI and assign a handle */
00990             int numnodes, c;
00991             raw1394handle_t handle;
00992             handle = dc1394_create_handle (p);
00993             if (handle == NULL)
00994               continue;
00995             
00996             /* Get the camera nodes */
00997             numnodes = raw1394_get_nodecount (handle);
00998             if (numnodes <= 1)
00999               continue;
01000             
01001             /* Get info for each camera node */
01002             for (c = 0; c < numnodes; c++)
01003               {
01004                 dc1394_camerainfo info;
01005                 if (dc1394_get_camera_info (handle, c, &info) < 0)
01006                   {
01007                     printf ("1394 card %d node %d is not a camera [INVALID]\n", p, c);
01008                   }
01009                 else
01010                   {
01011                     printf ("1394 card %d node %d is a [%s - %s] --> ", p, c, info.vendor, info.model);
01012                     
01013                     /* Store the node numbers */
01014                     if (*card == -1)
01015                       {
01016                         printf ("auto detected\n");
01017                         *card = p;
01018                         *node = c;
01019                       }
01020                     else
01021                       printf ("not used\n");
01022                   }
01023               }
01024           }
01025         
01026         /* If we still haven't found a camera then we are in trouble */
01027         if ((*card == -1) && (*node == -1))
01028           {
01029             fprintf (stderr, "Could not auto detect any cameras on the %d firewire cards available\n", numPorts);
01030             exit (1);
01031           }
01032         printf ("Using the firewire camera on card %d and node %d\n", *card, *node);
01033       }
01034     
01035     
01036     /* Lets create a handle so it can be used later on */
01037     arV1394.handle = dc1394_create_handle(*card);
01038     if (arV1394.handle==NULL)
01039       {
01040         fprintf (stderr, "Could not acquire a raw1394 handle, did you insmod the drivers?\n");
01041         exit(1);
01042       }
01043     
01044     
01045     /* Success */
01046     return 0;
01047 }
01048 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00