Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
204 chris 1
/*
2
  1394 Linux Firewire Digital Camera Interface
3
  Copyright (C) 2002 - 2006
4
  Kiyoshi Kiyokawa (kiyo@crl.go.jp)
5
  Hirokazu Kato (kato@sys.im.hiroshima-cu.ac.jp)
6
  Wayne Piekarski (wayne@cs.unisa.edu.au)
7
 
8
  $Id: video.c,v 1.14 2006/09/19 03:13:10 philip_lamb Exp $
9
  This source file is dual licensed under either the GPL or the LGPL license
10
  by the authors of this software.
11
 
12
  --
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
16
  the Free Software Foundation; either version 2 of the License, or
17
  (at your option) any later version.
18
 
19
  This program is distributed in the hope that it will be useful,
20
  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
  GNU General Public License for more details.
23
 
24
  You should have received a copy of the GNU General Public License
25
  along with this program; if not, write to the Free Software
26
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 
28
  --
29
 
30
  This library is free software; you can redistribute it and/or
31
  modify it under the terms of the GNU Lesser General Public
32
  License as published by the Free Software Foundation; either
33
  version 2.1 of the License, or (at your option) any later version.
34
 
35
  This library is distributed in the hope that it will be useful,
36
  but WITHOUT ANY WARRANTY; without even the implied warranty of
37
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
38
  Lesser General Public License for more details.
39
 
40
  You should have received a copy of the GNU Lesser General Public
41
  License along with this library; if not, write to the Free Software
42
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
43
 
44
 
45
/*
46
 *   Revision: 1.0   Date: 2002/01/01
47
 *   Video capture subrutine for Linux/libdc1394 devices
48
 *   author: Kiyoshi Kiyokawa ( kiyo@crl.go.jp )
49
 *           Hirokazu Kato ( kato@sys.im.hiroshima-cu.ac.jp )
50
 *
51
 *
52
 *   Revision: 1.1   Date: 2004/09/30
53
 *   Modifications by Wayne Piekarski ( wayne@cs.unisa.edu.au )
54
 *   - #ifdef macros added to support the many different versions of libdc1394
55
 *   - Initialisation code rewritten to support multiple 1394 busses
56
 *   - Either autodetect of cameras or specifying the exact camera is now possible
57
 *   - Support for changing of various 1394 camera properties
58
 *
59
 *
60
 *   Revision 1.1.1  Date: 2005/03/14
61
 *   - Patch by Henrik Erkkonen to support version 11 of libdc1394.
62
 *   - (Removed in later 1.3 changes by Wayne)
63
 *
64
 *
65
 *   Revision: 1.2   Date: 2005/07/20
66
 *   Modifications by Wayne Piekarski ( wayne@cs.unisa.edu.au )
67
 *   - Added support for Bayer image tiling for Point Grey DragonFly cameras
68
 *
69
 *
70
 *   Revision: 1.3   Date: 2006/09/16 ( wayne@cs.unisa.edu.au )
71
 *   - Stabilised interfaces around latest libdc1394 libraries
72
 *   - Added various other cleanups and bug fixes to make the code more stable
73
 *   - Added licensing allowing LGPL or existing GPL with permission from original authors
74
 *   - Rearranged various constants from AR/config.h to make things easier to understand
75
 *   - Better config string support with ARTOOLKIT_CONFIG to override defaults from the shell
76
 *
77
 */
78
 
79
#include <sys/ioctl.h>
80
#include <sys/types.h>
81
#include <sys/stat.h>
82
#include <sys/mman.h>
83
#include <fcntl.h>
84
#include <unistd.h>
85
#include <stdio.h>
86
#include <stdlib.h>
87
#include <string.h>
88
#include <linux/types.h>
89
#include <libraw1394/raw1394.h>
90
#include <libdc1394/dc1394_control.h>
91
#include <AR/config.h>
92
#include <AR/ar.h>
93
#include <AR/video.h>
94
 
95
 
96
 
97
 
98
/* Do not touch the following macros! */
99
#undef  LIBDC_8
100
#undef  LIBDC_9
101
#undef  LIBDC_10
102
#undef  LIBDC_11
103
#undef  LIBDC_DEF
104
 
105
 
106
/* ----------------------- MAKE ANY #define CHANGES HERE ONLY -------------------------------- */
107
/* This define controls if we use the new or old libDC1394 API functions. In the past there were
108
   many development releases, but the latest 1.0.0 release is stable and modern Linux distributions
109
   have all standardised on this, so there is no need to make changes here any more. */
110
// #define LIBDC_8
111
// #define LIBDC_9
112
// #define LIBDC_10
113
#define LIBDC_11
114
/* ----------------------- MAKE ANY #define CHANGES HERE ONLY -------------------------------- */
115
 
116
 
117
/* These are some extra constants I defined for my modifications */
118
#define DEFAULT_VIDEO_CARD -1
119
#define MAX_PORTS 4 /* This is the maximum number of Firewire cards we can have installed in the system, it is an arbitrary number */
120
 
121
 
122
 
123
 
124
/* Defines that control various aspects of this code */
125
#define   VIDEO_NODE_ANY                      -1
126
#define   VIDEO_MODE_320x240_YUV422           32
127
#define   VIDEO_MODE_640x480_YUV411           33
128
#define   VIDEO_MODE_640x480_RGB              34
129
#define   VIDEO_MODE_640x480_YUV411_HALF      35
130
#define   VIDEO_MODE_640x480_MONO             36
131
#define   VIDEO_MODE_640x480_MONO_COLOR       37
132
#define   VIDEO_MODE_640x480_MONO_COLOR_HALF  38
133
#define   VIDEO_FRAME_RATE_1_875               1
134
#define   VIDEO_FRAME_RATE_3_75                2
135
#define   VIDEO_FRAME_RATE_7_5                 3
136
#define   VIDEO_FRAME_RATE_15                  4
137
#define   VIDEO_FRAME_RATE_30                  5
138
#define   VIDEO_FRAME_RATE_60                  6
139
#define   DEFAULT_VIDEO_NODE                   VIDEO_NODE_ANY
140
#define   DEFAULT_VIDEO_MODE                   VIDEO_MODE_640x480_YUV411_HALF
141
#define   DEFAULT_VIDEO_FRAME_RATE             VIDEO_FRAME_RATE_30
142
 
143
 
144
 
145
 
146
/* Error checking to ensure we have a proper configuration, and put some debugging out */
147
#ifdef LIBDC_8
148
#warning Compiling using original 0.8.3 libDC library (single camera only) - debian: libdc1394-8-dev
149
#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!
150
#define LIBDC_DEF
151
#endif
152
 
153
#ifdef LIBDC_9
154
#warning Compiling using an older 0.9.1 libDC library (multiple camera support) - debian: libdc1394-9-dev
155
#define LIBDC_DEF
156
#endif
157
 
158
#ifdef LIBDC_10
159
#warning Compiling using an older 0.9.5 libDC library (multiple camera support) - debian: libdc1394-10-dev
160
#define LIBDC_DEF
161
#endif
162
 
163
#ifdef LIBDC_11
164
// #warning Compiling using the stable 1.0.0 libDC library (multiple camera support) - debian: libdc1394-11-dev
165
#define LIBDC_DEF
166
#endif
167
 
168
#ifndef LIBDC_DEF
169
#error One of the LIBDC_[8,9,10,11] macros must be defined to compile this code properly!
170
#endif
171
 
172
 
173
 
174
 
175
/* Here are some extra definitions to support Point Grey DragonFly cameras */
176
#include "conversions.h"
177
int ar2Video_dragonfly = -1;
178
 
179
 
180
 
181
 
182
static AR2VideoParamT   *gVid = NULL;
183
 
184
int arVideoDispOption( void )
185
{
186
    return  ar2VideoDispOption();
187
}
188
 
189
int arVideoOpen( char *config )
190
{
191
    if( gVid != NULL ) {
192
      fprintf(stderr, "The device has already been opened!\n");
193
      exit (1);
194
    }
195
    gVid = ar2VideoOpen( config );
196
    if (gVid == NULL)
197
      return (-1);
198
 
199
    return 0;
200
}
201
 
202
int arVideoClose( void )
203
{
204
  int result;
205
 
206
  if( gVid == NULL ) return -1;
207
 
208
  result = ar2VideoClose(gVid);
209
  gVid = NULL;
210
  return (result);
211
}
212
 
213
int arVideoInqSize( int *x, int *y )
214
{
215
    if( gVid == NULL ) return -1;
216
 
217
    return ar2VideoInqSize( gVid, x, y );
218
}
219
 
220
ARUint8 *arVideoGetImage( void )
221
{
222
    if( gVid == NULL ) return NULL;
223
 
224
    return ar2VideoGetImage( gVid );
225
}
226
 
227
int arVideoCapStart( void )
228
{
229
    if( gVid == NULL ) return -1;
230
 
231
    return ar2VideoCapStart( gVid );
232
}
233
 
234
int arVideoCapStop( void )
235
{
236
    if( gVid == NULL ) return -1;
237
 
238
    return ar2VideoCapStop( gVid );
239
}
240
 
241
int arVideoCapNext( void )
242
{
243
    if( gVid == NULL ) return -1;
244
 
245
    return ar2VideoCapNext( gVid );
246
}
247
 
248
/*-------------------------------------------*/
249
 
250
 
251
typedef struct __arVideo1394
252
{
253
    raw1394handle_t         handle;
254
} ARVideo1394;
255
 
256
static ARVideo1394   arV1394;
257
static int           initFlag = 0;
258
 
259
static int ar2Video1394Init( int debug, int *card, int *node );
260
 
261
 
262
int ar2VideoDispOption( void )
263
{
264
    printf ("\n");
265
    printf("ARVideo may be configured using one or more of the following options, separated by a space:\n\n");
266
    printf(" -node=N\n");
267
    printf("    specifies detected node ID of a FireWire camera (-1: Any).\n");
268
    printf(" -card=N\n");
269
    printf("    specifies the FireWire adaptor id number (-1: Any).\n");
270
    printf(" -mode=[320x240_YUV422|640x480_RGB|640x480_YUV411]\n");
271
    printf("    specifies input image format.\n");
272
    printf(" -rate=N\n");
273
    printf("    specifies desired framerate of a FireWire camera. \n");
274
    printf("    (1.875, 3.75, 7.5, 15, 30, 60)\n");
275
    printf(" -[name]=N  where name is brightness, iris, shutter, gain, saturation, gamma, sharpness\n");
276
    printf("    (value must be a legal value for this parameter - use coriander to find what they are\n");
277
    printf("\n");
278
    printf(" Note that if no config string is supplied, you can override it with the environment variable ARTOOLKIT_CONFIG\n");
279
    printf("\n");
280
 
281
    return 0;
282
}
283
 
284
AR2VideoParamT *ar2VideoOpen( char *config_in )
285
{
286
    char                      video1394devname [128];
287
    AR2VideoParamT            *vid;
288
    ARUint32                  p1,p2;
289
    quadlet_t                 value;
290
    char                      *config, *a, line[256];
291
    int                       i;
292
 
293
    int brightness = -1;
294
    int iris = -1;
295
    int shutter = -1;
296
    int gain = -1;
297
    int saturation = -1;
298
    int gamma = -1;
299
    int sharpness = -1;
300
 
301
    arMalloc( vid, AR2VideoParamT, 1 );
302
    vid->node         = DEFAULT_VIDEO_NODE;
303
    vid->card         = DEFAULT_VIDEO_CARD;
304
    vid->mode         = DEFAULT_VIDEO_MODE;
305
    vid->rate         = DEFAULT_VIDEO_FRAME_RATE;
306
    vid->channel      = 0;
307
    vid->speed        = SPEED_400;
308
    vid->format       = FORMAT_VGA_NONCOMPRESSED;
309
    vid->dma_buf_num  = 16;
310
    vid->debug        = 0;
311
    vid->status       = 0;
312
 
313
        /* If no config string is supplied, we should use the environment variable, otherwise set a sane default */
314
        if (!config_in || !(config_in[0])) {
315
                /* None suppplied, lets see if the user supplied one from the shell */
316
                char *envconf = getenv ("ARTOOLKIT_CONFIG");
317
                if (envconf && envconf[0]) {
318
                        config = envconf;
319
                        printf ("Using config string from environment [%s].\n", envconf);
320
                } else {
321
                        config = NULL;
322
                        printf ("No video config string supplied, using defaults.\n");
323
                }
324
        } else {
325
                config = config_in;
326
                printf ("Using supplied video config string [%s].\n", config_in);
327
        }
328
 
329
        a = config;
330
    if( a != NULL) {
331
        for(;;) {
332
            while( *a == ' ' || *a == '\t' ) a++;
333
            if( *a == '\0' ) break;
334
 
335
            if( strncmp( a, "-mode=", 6 ) == 0 ) {
336
                if ( strncmp( &a[6], "320x240_YUV422", 14 ) == 0 ) {
337
                    vid->mode = VIDEO_MODE_320x240_YUV422;
338
                }
339
                else if ( strncmp( &a[6], "640x480_YUV411", 14 ) == 0 ) {
340
                    vid->mode = VIDEO_MODE_640x480_YUV411;
341
                }
342
                else if ( strncmp( &a[6], "640x480_RGB", 11 ) == 0 ) {
343
                    vid->mode = VIDEO_MODE_640x480_RGB;
344
                }
345
                else {
346
                    ar2VideoDispOption();
347
                    free( vid );
348
                    return 0;
349
                }
350
            }
351
 
352
            else if( strncmp( a, "-iris=", 6 ) == 0 ) {
353
                sscanf( a, "%s", line );
354
                if( sscanf( &line[6], "%d", &iris ) == 0 ) {
355
                    ar2VideoDispOption();
356
                    free( vid );
357
                    return 0;
358
                }
359
            }
360
            else if( strncmp( a, "-gain=", 6 ) == 0 ) {
361
                sscanf( a, "%s", line );
362
                if( sscanf( &line[6], "%d", &gain ) == 0 ) {
363
                    ar2VideoDispOption();
364
                    free( vid );
365
                    return 0;
366
                }
367
            }
368
 
369
            else if( strncmp( a, "-node=", 6 ) == 0 ) {
370
                sscanf( a, "%s", line );
371
                if( sscanf( &line[6], "%d", &vid->node ) == 0 ) {
372
                    ar2VideoDispOption();
373
                    free( vid );
374
                    return 0;
375
                }
376
            }
377
            else if( strncmp( a, "-card=", 6 ) == 0 ) {
378
                sscanf( a, "%s", line );
379
                if( sscanf( &line[6], "%d", &vid->card ) == 0 ) {
380
                    ar2VideoDispOption();
381
                    free( vid );
382
                    return 0;
383
                }
384
            }
385
            else if( strncmp( a, "-rate=", 6 ) == 0 ) {
386
                if ( strncmp( &a[6], "1.875", 5 ) == 0 ) {
387
                    vid->rate = VIDEO_FRAME_RATE_1_875;
388
                }
389
                else if ( strncmp( &a[6], "3.75", 4 ) == 0 ) {
390
                    vid->rate = VIDEO_FRAME_RATE_3_75;
391
                }
392
                else if ( strncmp( &a[6], "7.5", 3 ) == 0 ) {
393
                    vid->rate = VIDEO_FRAME_RATE_7_5;
394
                }
395
                else if ( strncmp( &a[6], "15", 2 ) == 0 ) {
396
                    vid->rate = VIDEO_FRAME_RATE_15;
397
                }
398
                else if ( strncmp( &a[6], "30", 2 ) == 0 ) {
399
                    vid->rate = VIDEO_FRAME_RATE_30;
400
                }
401
                else if ( strncmp( &a[6], "60", 2 ) == 0 ) {
402
                    vid->rate = VIDEO_FRAME_RATE_60;
403
                }
404
                else {
405
                    ar2VideoDispOption();
406
                    free( vid );
407
                    return 0;
408
                }
409
            }
410
            else if( strncmp( a, "-debug", 6 ) == 0 ) {
411
                vid->debug = 1;
412
            }
413
            else if( strncmp( a, "-adjust", 7 ) == 0 ) {
414
              /* Do nothing - this is for V4L compatibility */
415
            }
416
            else {
417
                ar2VideoDispOption();
418
                free( vid );
419
                return 0;
420
            }
421
 
422
            while( *a != ' ' && *a != '\t' && *a != '\0') a++;
423
        }
424
    }
425
 
426
 
427
    if( initFlag == 0 )
428
      {
429
        if( ar2Video1394Init(vid->debug, &vid->card, &vid->node) < 0 )
430
          {
431
            fprintf (stderr, "Could not initialise 1394\n");
432
            exit(1);
433
          }
434
        initFlag = 1;
435
      }
436
 
437
    switch( vid->mode )
438
      {
439
      case VIDEO_MODE_320x240_YUV422:
440
        vid->int_mode = MODE_320x240_YUV422;
441
        break;
442
      case VIDEO_MODE_640x480_YUV411:
443
        vid->int_mode = MODE_640x480_YUV411;
444
        break;
445
      case VIDEO_MODE_640x480_RGB:
446
        vid->int_mode = MODE_640x480_RGB;
447
        break;
448
      default:
449
        printf("Sorry, Unsupported Video Format for IEEE1394 Camera.\n");
450
        exit(1);
451
        break;
452
      }
453
 
454
 
455
    switch( vid->rate ) {
456
        case VIDEO_FRAME_RATE_1_875:
457
          vid->int_rate = FRAMERATE_1_875;
458
          break;
459
        case VIDEO_FRAME_RATE_3_75:
460
          vid->int_rate = FRAMERATE_3_75;
461
          break;
462
        case VIDEO_FRAME_RATE_7_5:
463
          vid->int_rate = FRAMERATE_7_5;
464
          break;
465
        case VIDEO_FRAME_RATE_15:
466
          vid->int_rate = FRAMERATE_15;
467
          break;
468
        case VIDEO_FRAME_RATE_30:
469
          vid->int_rate = FRAMERATE_30;
470
          break;
471
        case VIDEO_FRAME_RATE_60:
472
          vid->int_rate = FRAMERATE_60;
473
          break;
474
        default:
475
          fprintf(stderr, "Sorry, Unsupported Frame Rate for IEEE1394 Camera.\n");
476
          exit(1);
477
    }
478
 
479
 
480
 
481
 
482
 
483
    /*-----------------------------------------------------------------------*/
484
    /*  report camera's features                                             */
485
    /*-----------------------------------------------------------------------*/
486
    if( dc1394_get_camera_feature_set(arV1394.handle,
487
                                      vid->node,
488
                                      &(vid->features)) != DC1394_SUCCESS ) {
489
        fprintf( stderr, "unable to get feature set\n");
490
    }
491
    else if( vid->debug ) {
492
      dc1394_print_feature_set( &(vid->features) );
493
    }
494
 
495
 
496
    /* Change the camera settings if we need to */
497
    if (iris != -1)
498
      {
499
        fprintf (stderr, "Adjusting IRIS setting to %d\n", iris);
500
        dc1394_set_iris (arV1394.handle, vid->node, (unsigned int)iris);
501
      }
502
    if (gain != -1)
503
      {
504
        fprintf (stderr, "Adjusting GAIN setting to %d\n", gain);
505
        dc1394_set_gain (arV1394.handle, vid->node, (unsigned int)gain);
506
      }
507
 
508
 
509
    /* Dump out the new parameters now - this is only for code testing */
510
    /* if (vid->debug)
511
       dc1394_print_feature_set( &(vid->features) ); */
512
 
513
 
514
    /*-----------------------------------------------------------------------*/
515
    /*  check parameters                                                     */
516
    /*-----------------------------------------------------------------------*/
517
    if( dc1394_query_supported_formats(arV1394.handle, vid->node, &value) != DC1394_SUCCESS ) {
518
      fprintf( stderr, "unable to query_supported_formats\n");
519
    }
520
    i = 31 - (FORMAT_VGA_NONCOMPRESSED - FORMAT_MIN);
521
    p1 = 1 << i;
522
    p2 = value & p1;
523
    if( p2 == 0 ) {
524
        fprintf( stderr, "unable to use this camera on VGA_NONCOMPRESSED format.\n");
525
        exit(0);
526
    }
527
 
528
    /* Check that the camera supports the particular video mode we asked for */
529
    dc1394_query_supported_modes(arV1394.handle, vid->node,  FORMAT_VGA_NONCOMPRESSED, &value);
530
    i = 31 - (vid->int_mode - MODE_FORMAT0_MIN);
531
    p1 = 1 << i;
532
    p2 = value & p1;
533
    if( p2 == 0 )
534
      {
535
        /* Test if the camera supports mono, if so then it is probably a dragonfly camera which uses mono but with Bayer encoding */
536
        i = 31 - (MODE_640x480_MONO - MODE_FORMAT0_MIN);
537
        p1 = 1 << i;
538
        p2 = value & p1;
539
        if (p2 == 0)
540
          {
541
            fprintf( stderr, "Unsupported Mode for the specified camera.\n");
542
            ar2VideoDispOption();
543
            exit(0);
544
          }
545
        else
546
          {
547
            fprintf (stderr, "Detected a mono camera, assuming DragonFly camera with Bayer image decoding\n");
548
            vid->int_mode = MODE_640x480_MONO;
549
            ar2Video_dragonfly = 1;
550
          }
551
      }
552
 
553
    dc1394_query_supported_framerates(arV1394.handle, vid->node, FORMAT_VGA_NONCOMPRESSED, vid->int_mode, &value);
554
    i = 31 - (vid->int_rate - FRAMERATE_MIN);
555
    p1 = 1 << i;
556
    p2 = value & p1;
557
    if( p2 == 0 ) {
558
        fprintf( stderr, "Unsupported Framerate for the specified mode.\n");
559
        ar2VideoDispOption();
560
        exit(0);
561
    }
562
 
563
 
564
    /* Decide on where the video1394 device nodes are, they can be either at
565
       /dev/video1394/ or /dev/video1394-* depending on the distribution */
566
    struct stat video_stat;
567
    if (stat ("/dev/video1394", &video_stat) < 0)
568
      sprintf (video1394devname, "/dev/video1394-%d", vid->card);
569
    else
570
      sprintf (video1394devname, "/dev/video1394/%d", vid->card);
571
 
572
 
573
    /*-----------------------------------------------------------------------*/
574
    /*  setup capture                                                        */
575
    /*-----------------------------------------------------------------------*/
576
    if( dc1394_dma_setup_capture(arV1394.handle,
577
                                 vid->node,
578
#ifndef LIBDC_8
579
                                 vid->node,
580
#else
581
                                 vid->channel,
582
#endif
583
                                 vid->format,
584
                                 vid->int_mode,
585
                                 vid->speed,
586
                                 vid->int_rate,
587
                                 vid->dma_buf_num,
588
#ifdef LIBDC_10
589
                                 0, /* do_extra_buffering */
590
#endif
591
#ifndef LIBDC_8
592
                                 1, video1394devname, /* drop_frames, dma_device_file */
593
#endif
594
                                 &(vid->camera)) != DC1394_SUCCESS ) {
595
        fprintf( stderr,"unable to setup camera-\n"
596
                "check if you did 'insmod video1394' or,\n"
597
                "check line %d of %s to make sure\n"
598
                "that the video mode,framerate and format are\n"
599
                "supported by your camera\n",
600
                __LINE__,__FILE__);
601
        exit(1);
602
    }
603
 
604
    /* set trigger mode */
605
    if( dc1394_set_trigger_mode(arV1394.handle, vid->node, TRIGGER_MODE_0) != DC1394_SUCCESS ) {
606
        fprintf( stderr, "unable to set camera trigger mode (ignored)\n");
607
    }
608
 
609
    arMalloc( vid->image, ARUint8, (vid->camera.frame_width * vid->camera.frame_height * AR_PIX_SIZE_DEFAULT) );
610
 
611
    return vid;
612
}
613
 
614
int ar2VideoClose( AR2VideoParamT *vid )
615
{
616
    int     i;
617
 
618
    if( vid->status > 0 ) ar2VideoCapStop( vid );
619
 
620
#if 0
621
    dc1394_dma_release_camera(arV1394.handle, &(vid->camera));
622
#endif
623
    free( vid->image );
624
    free( vid );
625
 
626
    raw1394_destroy_handle(arV1394.handle);
627
    initFlag = 0;
628
 
629
    return 0;
630
}
631
 
632
int ar2VideoCapStart( AR2VideoParamT *vid )
633
{
634
    char video1394devname [128];
635
 
636
 
637
    if(vid->status != 0 && vid->status != 3){
638
        fprintf(stderr, "arVideoCapStart has already been called.\n");
639
        return -1;
640
    }
641
 
642
    /*-----------------------------------------------------------------------*/
643
    /*  setup capture                                                        */
644
    /*-----------------------------------------------------------------------*/
645
    struct stat video_stat;
646
    if (stat ("/dev/video1394", &video_stat) < 0)
647
      sprintf (video1394devname, "/dev/video1394-%d", vid->card);
648
    else
649
      sprintf (video1394devname, "/dev/video1394/%d", vid->card);
650
    if( vid->status == 3 ) {
651
        if( dc1394_dma_setup_capture(arV1394.handle,
652
                                     vid->node,
653
#ifndef LIBDC_8
654
                                     vid->node,
655
#else
656
                                     vid->channel,
657
#endif
658
                                     vid->format,
659
                                     vid->int_mode,
660
                                     vid->speed,
661
                                     vid->int_rate,
662
                                     vid->dma_buf_num,
663
#ifdef LIBDC_10
664
                                     0, /* do_extra_buffering */
665
#endif
666
#ifndef LIBDC_8
667
                                     1, video1394devname, /* drop_frames, dma_device_file */
668
#endif
669
                                     &(vid->camera)) != DC1394_SUCCESS ) {
670
            fprintf( stderr,"unable to setup camera-\n"
671
                    "check if you did 'insmod video1394' or,\n"
672
                    "check line %d of %s to make sure\n"
673
                    "that the video mode,framerate and format are\n"
674
                    "supported by your camera\n",
675
                    __LINE__,__FILE__);
676
            exit(1);
677
        }
678
    }
679
 
680
    if( dc1394_start_iso_transmission(arV1394.handle, vid->node) != DC1394_SUCCESS ) {
681
        fprintf( stderr, "unable to start camera iso transmission\n");
682
        return -1;
683
    }
684
 
685
    vid->status = 1;
686
 
687
    return 0;
688
}
689
 
690
int ar2VideoCapNext( AR2VideoParamT *vid )
691
{
692
    if(vid->status == 0 || vid->status == 3){
693
        fprintf(stderr, "arVideoCapStart has never been called.\n");
694
        return -1;
695
    }
696
    if(vid->status == 2) vid->status = 1;
697
 
698
    dc1394_dma_done_with_buffer( &(vid->camera) );
699
 
700
    return 0;
701
}
702
 
703
int ar2VideoCapStop( AR2VideoParamT *vid )
704
{
705
    if(vid->status == 2){
706
        if( dc1394_dma_single_capture( &(vid->camera) ) != DC1394_SUCCESS ) {
707
            fprintf( stderr, "unable to capture a frame\n");
708
        }
709
    }
710
    if(vid->status == 0){
711
        fprintf(stderr, "arVideoCapStart has never been called.\n");
712
        return -1;
713
    }
714
    vid->status = 3;
715
 
716
    if( dc1394_stop_iso_transmission(arV1394.handle, vid->node) != DC1394_SUCCESS ) {
717
        fprintf(stderr, "couldn't stop the camera?\n");
718
        return -1;
719
    }
720
 
721
    dc1394_dma_release_camera(arV1394.handle, &(vid->camera));
722
 
723
    return 0;
724
}
725
 
726
int ar2VideoInqSize(AR2VideoParamT *vid, int *x,int *y)
727
{
728
    *x = vid->camera.frame_width;
729
    *y = vid->camera.frame_height;
730
 
731
    return 0;
732
}
733
 
734
ARUint8 *ar2VideoGetImage( AR2VideoParamT *vid )
735
{
736
    register ARUint8 *buf, *buf2;
737
    register int i, j;
738
    register int U, V, R, G, B, V2, U5, UV;
739
    register int Y0, Y1, Y2, Y3;
740
    register ARUint8 r, g, b;
741
 
742
    if(vid->status == 0){
743
        fprintf(stderr, "arVideoCapStart has never been called.\n");
744
        return NULL;
745
    }
746
    if(vid->status == 2){
747
        fprintf(stderr, "arVideoCapNext has never been called since previous arVideoGetImage.\n");
748
        return NULL;
749
    }
750
 
751
    if( dc1394_dma_single_capture( &(vid->camera) ) != DC1394_SUCCESS ) {
752
        fprintf(stderr, "unable to capture a frame\n");
753
        return NULL;
754
    }
755
    vid->status = 2;
756
 
757
 
758
    switch( vid->int_mode ) {
759
        case MODE_640x480_RGB:
760
          return (ARUint8 *)vid->camera.capture_buffer;
761
 
762
 
763
        case MODE_640x480_MONO:
764
          {
765
            /* We only currently support Bayer image decoding from Point Grey cameras */
766
            if (ar2Video_dragonfly < 0)
767
              {
768
                fprintf (stderr, "It is not possible to be in mono mode without the dragonfly flag being set previously\n");
769
                exit (1);
770
              }
771
 
772
            /* If the image data is NULL then we should immediately return to avoid doing an image conversion which probably won't work! */
773
            if (vid->camera.capture_buffer == NULL)
774
              return ((ARUint8 *)vid->camera.capture_buffer);
775
 
776
            /* 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 */
777
 
778
            /* Query the camera to detect the Bayer pattern type */
779
            quadlet_t qValue;
780
            GetCameraControlRegister (arV1394.handle, vid->node, 0x1040, &qValue);
781
            bayer_pattern_t pattern = BAYER_PATTERN_BGGR;
782
            static bayer_pattern_t prev_pattern = -1;
783
            switch( qValue )
784
              {
785
              case 0x42474752:  /* BGGR */
786
                pattern = BAYER_PATTERN_BGGR;
787
                break;
788
              case 0x47524247:  /* GRBG */
789
                pattern = BAYER_PATTERN_GRBG;
790
                break;
791
              case 0x52474742:  /* RGGB */
792
                pattern = BAYER_PATTERN_RGGB;
793
                break;
794
              case 0x47425247:  /* GBRG */
795
                pattern = BAYER_PATTERN_GBRG;
796
                break;
797
              case 0x59595959:  /* YYYY = BW */
798
                fprintf (stderr, "Camera is black and white, Bayer conversion is not possible\n");
799
                exit (1);
800
              default:
801
                if (prev_pattern == -1)
802
                  {
803
                    fprintf (stderr, "Camera BAYER_TILE_MAPPING register has an unexpected value 0x%x on initial startup, which should not occur\n", qValue);
804
                    exit (1);
805
                  }
806
                else
807
                  {
808
                    /* This is a wierd bug where occasionally you get an invalid register value and I have no idea why this is */
809
                    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);
810
                    pattern = prev_pattern;
811
                  }
812
              }
813
 
814
            /* Store the previous Bayer pattern value */
815
            prev_pattern = pattern;
816
 
817
            /* Do the Bayer image conversion now */
818
            unsigned char *dest  = vid->image;
819
            unsigned char *src = (ARUint8 *)vid->camera.capture_buffer;
820
            BayerNearestNeighbor( src,
821
                            dest,
822
                            vid->camera.frame_width,
823
                            vid->camera.frame_height,
824
                            pattern );
825
 
826
            /* Image is done, we can now return it! */
827
            return (vid->image);               
828
          }
829
 
830
 
831
        case MODE_640x480_YUV411:
832
          buf  = vid->image;
833
          buf2 = (ARUint8 *)vid->camera.capture_buffer;
834
          for( i = vid->camera.frame_height * vid->camera.frame_width / 4; i; i--) {
835
              U   = ((ARUint8)*buf2++ - 128) * 0.354;
836
              U5  = 5*U;
837
              Y0  = (ARUint8)*buf2++;
838
              Y1  = (ARUint8)*buf2++;
839
              V   = ((ARUint8)*buf2++ - 128) * 0.707;
840
              V2  = 2*V;
841
              Y2  = (ARUint8)*buf2++;
842
              Y3  = (ARUint8)*buf2++;
843
              UV  = - U - V;
844
 
845
              // Original equations
846
              // R = Y           + 1.402 V
847
              // G = Y - 0.344 U - 0.714 V
848
              // B = Y + 1.772 U
849
              R = Y0 + V2;
850
              if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
851
 
852
              G = Y0 + UV;
853
              if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
854
 
855
              B = Y0 + U5;
856
              if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
857
 
858
              *buf++ = (ARUint8)R;
859
              *buf++ = (ARUint8)G;
860
              *buf++ = (ARUint8)B;
861
 
862
              //---
863
              R = Y1 + V2;
864
              if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
865
 
866
              G = Y1 + UV;
867
              if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
868
 
869
              B = Y1 + U5;
870
              if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
871
 
872
              *buf++ = (ARUint8)R;
873
              *buf++ = (ARUint8)G;
874
              *buf++ = (ARUint8)B;
875
 
876
              //---
877
              R = Y2 + V2;
878
              if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
879
 
880
              G = Y2 + UV;
881
              if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
882
 
883
              B = Y2 + U5;
884
              if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
885
 
886
              *buf++ = (ARUint8)R;
887
              *buf++ = (ARUint8)G;
888
              *buf++ = (ARUint8)B;
889
 
890
              //---
891
              R = Y3 + V2;
892
              if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
893
 
894
              G = Y3 + UV;
895
              if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
896
 
897
              B = Y3 + U5;
898
              if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
899
 
900
              *buf++ = (ARUint8)R;
901
              *buf++ = (ARUint8)G;
902
              *buf++ = (ARUint8)B;
903
          }
904
          return vid->image;
905
 
906
        case MODE_320x240_YUV422:
907
          buf  = vid->image;
908
          buf2 = (ARUint8 *)vid->camera.capture_buffer;
909
          for( i = vid->camera.frame_height * vid->camera.frame_width / 2; i; i-- ) {
910
              U   = ((ARUint8)*buf2++ - 128) * 0.354;
911
              U5  = 5*U;
912
              Y0  = (ARUint8)*buf2++;
913
              V   = ((ARUint8)*buf2++ - 128) * 0.707;
914
              V2  = 2*V;
915
              Y1  = (ARUint8)*buf2++;
916
              UV  = - U - V;
917
 
918
              //---
919
              R = Y0 + V2;
920
              if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
921
 
922
              G = Y0 + UV;
923
              if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
924
 
925
              B = Y0 + U5;
926
              if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
927
 
928
              *buf++ = (ARUint8)R;
929
              *buf++ = (ARUint8)G;
930
              *buf++ = (ARUint8)B;
931
 
932
              //---
933
              R = Y1 + V2;
934
              if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
935
 
936
              G = Y1 + UV;
937
              if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
938
 
939
              B = Y1 + U5;
940
              if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
941
 
942
              *buf++ = (ARUint8)R;
943
              *buf++ = (ARUint8)G;
944
              *buf++ = (ARUint8)B;
945
          }
946
          return vid->image;
947
    }
948
 
949
    return NULL;
950
}
951
 
952
 
953
 
954
 
955
static int ar2Video1394Init( int debug, int *card, int *node )
956
{
957
    int     i;
958
 
959
    /* The user must either specify both card and node, or neither of them */
960
    if (((*card == -1) && (*node != -1)) ||
961
        ((*card != -1) && (*node == -1)))
962
      {
963
        fprintf (stderr, "Card value is %d and node value is %d, you must either auto-detect both or specify both\n", *card, *node);
964
        exit (1);
965
      }
966
 
967
    /* If the user has specified so, we will autodetect for the camera and grab the first one we can find */
968
    if ((*card == -1) && (*node == -1))
969
      {
970
        /* Find the total number of firewire cards in the system */
971
        int numPorts = MAX_PORTS;
972
        int p;
973
        struct raw1394_portinfo ports[MAX_PORTS];
974
        raw1394handle_t raw_handle = raw1394_new_handle ();
975
        if (raw_handle == NULL)
976
          {
977
            fprintf (stderr, "Could not acquire a raw1394 handle - driver not installed?\n");
978
            exit (1);
979
          }
980
        numPorts = raw1394_get_port_info (raw_handle, ports, numPorts);
981
        raw1394_destroy_handle (raw_handle);
982
 
983
        /* Perform autodetection */
984
        printf ("Auto-detecting firewire camera because card and node is not specified\n");
985
 
986
        /* We need to traverse all available cards and process each one */
987
        for (p = 0; p < numPorts; p++)
988
          {
989
            /* Open up OHCI and assign a handle */
990
            int numnodes, c;
991
            raw1394handle_t handle;
992
            handle = dc1394_create_handle (p);
993
            if (handle == NULL)
994
              continue;
995
 
996
            /* Get the camera nodes */
997
            numnodes = raw1394_get_nodecount (handle);
998
            if (numnodes <= 1)
999
              continue;
1000
 
1001
            /* Get info for each camera node */
1002
            for (c = 0; c < numnodes; c++)
1003
              {
1004
                dc1394_camerainfo info;
1005
                if (dc1394_get_camera_info (handle, c, &info) < 0)
1006
                  {
1007
                    printf ("1394 card %d node %d is not a camera [INVALID]\n", p, c);
1008
                  }
1009
                else
1010
                  {
1011
                    printf ("1394 card %d node %d is a [%s - %s] --> ", p, c, info.vendor, info.model);
1012
 
1013
                    /* Store the node numbers */
1014
                    if (*card == -1)
1015
                      {
1016
                        printf ("auto detected\n");
1017
                        *card = p;
1018
                        *node = c;
1019
                      }
1020
                    else
1021
                      printf ("not used\n");
1022
                  }
1023
              }
1024
          }
1025
 
1026
        /* If we still haven't found a camera then we are in trouble */
1027
        if ((*card == -1) && (*node == -1))
1028
          {
1029
            fprintf (stderr, "Could not auto detect any cameras on the %d firewire cards available\n", numPorts);
1030
            exit (1);
1031
          }
1032
        printf ("Using the firewire camera on card %d and node %d\n", *card, *node);
1033
      }
1034
 
1035
 
1036
    /* Lets create a handle so it can be used later on */
1037
    arV1394.handle = dc1394_create_handle(*card);
1038
    if (arV1394.handle==NULL)
1039
      {
1040
        fprintf (stderr, "Could not acquire a raw1394 handle, did you insmod the drivers?\n");
1041
        exit(1);
1042
      }
1043
 
1044
 
1045
    /* Success */
1046
    return 0;
1047
}
1048