• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* This is the contributed code:
2 Firewire and video4linux camera support for videoio
3 
4 2003-03-12  Magnus Lundin
5 lundin@mlu.mine.nu
6 
7 THIS EXEPERIMENTAL CODE
8 Tested on 2.4.19 with 1394, video1394, v4l, dc1394 and raw1394 support
9 
10 This set of files adds support for firevre and usb cameras.
11 First it tries to install a firewire camera,
12 if that fails it tries a v4l/USB camera
13 
14 It has been tested with the motempl sample program
15 
16 INSTALLATION
17 Install OpenCV
18 Install v4l
19 Install dc1394 raw1394 - coriander should work with your camera
20     Backup videoio folder
21     Copy new files
22     cd into videoio folder
23     make clean  (cvcap.cpp must be rebuilt)
24     make
25     make install
26 
27 
28 The build is controlled by the following entries in the videoio Makefile:
29 
30 libvideoio_la_LIBADD = -L/usr/X11R6/lib -lXm -lMrm -lUil -lpng  -ljpeg -lz -ltiff -lavcodec -lraw1394 -ldc1394_control
31 DEFS = -DHAVE_CONFIG_H -DHAVE_DC1394 HAVE_CAMV4L
32 
33 
34 Now it should be possible to use videoio camera functions, works for me.
35 
36 
37 THINGS TO DO
38 Better ways to select 1394 or v4l camera
39 Better support for videosize
40 Format7
41 
42 Comments and changes welcome
43 /Magnus
44 
45 2005-10-19 Roman Stanchak
46 rstanchak@yahoo.com
47 
48 Support added for setting MODE and other DC1394 properties.  Also added CONVERT_RGB flag
49 which indicates whether or not color conversion is performed in cvRetrieveFrame.  The default
50 for CONVERT_RGB=1 for backward compatibility.
51 
52 Tested with 2.6.12 with libdc1394-1.0.0, libraw1394-0.10.1 using a Point Grey Flea
53 
54 */
55 
56 
57 /*M///////////////////////////////////////////////////////////////////////////////////////
58 //
59 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
60 //
61 //  By downloading, copying, installing or using the software you agree to this license.
62 //  If you do not agree to this license, do not download, install,
63 //  copy or use the software.
64 //
65 //
66 //                        Intel License Agreement
67 //                For Open Source Computer Vision Library
68 //
69 // Copyright (C) 2000, Intel Corporation, all rights reserved.
70 // Third party copyrights are property of their respective owners.
71 //
72 // Redistribution and use in source and binary forms, with or without modification,
73 // are permitted provided that the following conditions are met:
74 //
75 //   * Redistribution's of source code must retain the above copyright notice,
76 //     this list of conditions and the following disclaimer.
77 //
78 //   * Redistribution's in binary form must reproduce the above copyright notice,
79 //     this list of conditions and the following disclaimer in the documentation
80 //     and/or other materials provided with the distribution.
81 //
82 //   * The name of Intel Corporation may not be used to endorse or promote products
83 //     derived from this software without specific prior written permission.
84 //
85 // This software is provided by the copyright holders and contributors "as is" and
86 // any express or implied warranties, including, but not limited to, the implied
87 // warranties of merchantability and fitness for a particular purpose are disclaimed.
88 // In no event shall the Intel Corporation or contributors be liable for any direct,
89 // indirect, incidental, special, exemplary, or consequential damages
90 // (including, but not limited to, procurement of substitute goods or services;
91 // loss of use, data, or profits; or business interruption) however caused
92 // and on any theory of liability, whether in contract, strict liability,
93 // or tort (including negligence or otherwise) arising in any way out of
94 // the use of this software, even if advised of the possibility of such damage.
95 //
96 //M*/
97 
98 #include "precomp.hpp"
99 
100 #if !defined WIN32 && defined HAVE_DC1394
101 
102 #include <unistd.h>
103 #include <stdint.h>
104 #include <libraw1394/raw1394.h>
105 #include <libdc1394/dc1394_control.h>
106 
107 #ifdef NDEBUG
108 #define CV_WARN(message)
109 #else
110 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
111 #endif
112 
113 #define CV_DC1394_CALL(expr)                                                  \
114 if((expr)<0){                                                                 \
115     OPENCV_ERROR(CV_StsInternal, "", "libdc1394 function call returned < 0"); \
116 }
117 
118 #define  DELAY              50000
119 
120 // bpp for 16-bits cameras... this value works for PtGrey DragonFly...
121 #define MONO16_BPP 8
122 
123 /* should be in pixelformat */
124 static void uyv2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels);
125 static void uyvy2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels);
126 static void uyyvyy2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels);
127 static void y2bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels);
128 static void y162bgr(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits);
129 static void rgb482bgr(const unsigned char *src8, unsigned char *dest, unsigned long long int NumPixels, int bits);
130 
131 static const char * videodev[4]={
132   "/dev/video1394/0",
133   "/dev/video1394/1",
134   "/dev/video1394/2",
135   "/dev/video1394/3"
136 };
137 
138 typedef struct CvCaptureCAM_DC1394
139 {
140     raw1394handle_t handle;
141     nodeid_t  camera_node;
142     dc1394_cameracapture* camera;
143     int format;
144     int mode;
145     int color_mode;
146     int frame_rate;
147     const char * device_name;
148     IplImage frame;
149     int convert;
150     int buffer_is_writeable;  // indicates whether frame.imageData is allocated by OpenCV or DC1394
151 }
152 CvCaptureCAM_DC1394;
153 
154 static void icvCloseCAM_DC1394( CvCaptureCAM_DC1394* capture );
155 
156 static int icvGrabFrameCAM_DC1394( CvCaptureCAM_DC1394* capture );
157 static IplImage* icvRetrieveFrameCAM_DC1394( CvCaptureCAM_DC1394* capture, int );
158 
159 static double icvGetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id );
160 static int    icvSetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id, double value );
161 
162 // utility functions
163 static int    icvFormatSupportedCAM_DC1394(int format, quadlet_t formats);
164 static int    icvModeSupportedCAM_DC1394(int format, int mode, quadlet_t modes);
165 static int    icvColorMode( int mode );
166 static unsigned int icvGetBestFrameRate( CvCaptureCAM_DC1394 * capture, int format, int mode);
167 static int    icvResizeFrame(CvCaptureCAM_DC1394 * capture);
168 
169 /***********************   Implementations  ***************************************/
170 #define MAX_PORTS 3
171 #define MAX_CAMERAS 8
172 #define NUM_BUFFERS 8
173 struct raw1394_portinfo ports[MAX_PORTS];
174 static raw1394handle_t handles[MAX_PORTS];
175 static int camCount[MAX_PORTS];
176 static int numPorts = -1;
177 static int numCameras = 0;
178 static nodeid_t *camera_nodes;
179 struct camnode {dc1394_cameracapture cam;int portnum;} cameras[MAX_CAMERAS];
180 
181 static const int preferred_modes[]
182 = {
183     // uncomment the following line to test a particular mode:
184     //FORMAT_VGA_NONCOMPRESSED, MODE_640x480_MONO16, 0,
185     FORMAT_SVGA_NONCOMPRESSED_2,
186     MODE_1600x1200_RGB, MODE_1600x1200_YUV422, MODE_1280x960_RGB, MODE_1280x960_YUV422,
187     MODE_1600x1200_MONO, MODE_1280x960_MONO, MODE_1600x1200_MONO16, MODE_1280x960_MONO16,
188     FORMAT_SVGA_NONCOMPRESSED_1,
189     MODE_1024x768_RGB, MODE_1024x768_YUV422, MODE_800x600_RGB, MODE_800x600_YUV422,
190     MODE_1024x768_MONO, MODE_800x600_MONO, MODE_1024x768_MONO16, MODE_800x600_MONO16,
191     FORMAT_VGA_NONCOMPRESSED,
192    MODE_640x480_RGB, MODE_640x480_YUV422, MODE_640x480_YUV411, MODE_320x240_YUV422,
193     MODE_160x120_YUV444, MODE_640x480_MONO, MODE_640x480_MONO16,
194     FORMAT_SCALABLE_IMAGE_SIZE,
195     MODE_FORMAT7_0, MODE_FORMAT7_1, MODE_FORMAT7_2, MODE_FORMAT7_3,
196     MODE_FORMAT7_4, MODE_FORMAT7_5, MODE_FORMAT7_6, MODE_FORMAT7_7,
197     0
198 };
199 
icvInitCapture_DC1394()200 void icvInitCapture_DC1394(){
201     int p;
202 
203     raw1394handle_t raw_handle = raw1394_new_handle();
204     if( raw_handle == 0 ) {
205         numPorts = 0;
206         return;
207     }
208     numPorts = raw1394_get_port_info(raw_handle, ports, MAX_PORTS);
209     raw1394_destroy_handle(raw_handle);
210     for (p = 0; p < numPorts; p++) {
211         handles[p] = dc1394_create_handle(p);
212         if (handles[p]==NULL) {  numPorts=-1; return; /*ERROR_CLEANUP_EXIT*/   }
213 
214         /* get the camera nodes and describe them as we find them */
215         camera_nodes = dc1394_get_camera_nodes(handles[p], &camCount[p], 0);
216         for (int i=0;i<camCount[p];i++) {
217             cameras[numCameras].cam.node = camera_nodes[i];
218             cameras[numCameras].portnum = p;
219             dc1394_stop_iso_transmission(handles[p], camera_nodes[i]);
220             numCameras++;
221         }
222     }
223 };
224 
icvCaptureFromCAM_DC1394(int index)225 static CvCaptureCAM_DC1394 * icvCaptureFromCAM_DC1394 (int index)
226 {
227     quadlet_t modes[8], formats;
228     int i;
229 
230     if (numPorts<0) icvInitCapture_DC1394();
231     if (numPorts==0)
232         return 0;     /* No i1394 ports found */
233     if (numCameras<1)
234         return 0;
235     if (index>=numCameras)
236         return 0;
237     if (index<0)
238         return 0;
239 
240     CvCaptureCAM_DC1394 * pcap = (CvCaptureCAM_DC1394*)cvAlloc(sizeof(*pcap));
241 
242     /* Select a port and camera */
243     pcap->device_name = videodev[cameras[index].portnum];
244     pcap->handle = handles[cameras[index].portnum];
245     pcap->camera = &cameras[index].cam;
246 
247     // get supported formats
248     if (dc1394_query_supported_formats(pcap->handle, pcap->camera->node, &formats)<0) {
249         fprintf(stderr,"%s:%d: Could not query supported formats\n",__FILE__,__LINE__);
250         formats=0x0;
251     }
252     for (i=0; i < NUM_FORMATS; i++) {
253         modes[i]=0;
254         if (icvFormatSupportedCAM_DC1394(i+FORMAT_MIN, formats)){
255             if (dc1394_query_supported_modes(pcap->handle, pcap->camera->node, i+FORMAT_MIN, &modes[i])<0) {
256                 fprintf(stderr,"%s:%d: Could not query Format%d modes\n",__FILE__,__LINE__,i);
257             }
258         }
259     }
260 
261     pcap->format = 0;
262     pcap->mode = 0;
263     pcap->color_mode = 0;
264     pcap->frame_rate = 0;
265 
266     int format_idx = -1;
267 
268     // scan the list of preferred modes, and find a supported one
269     for(i=0; (pcap->mode == 0) && (preferred_modes[i] != 0); i++) {
270         if((preferred_modes[i] >= FORMAT_MIN) && (preferred_modes[i] <= FORMAT_MAX)) {
271             pcap->format = preferred_modes[i];
272             format_idx = preferred_modes[i] - FORMAT_MIN;
273             continue;
274         }
275         assert(format_idx != -1);
276         if ( ! icvFormatSupportedCAM_DC1394(pcap->format, formats) )
277             continue;
278         if ( icvModeSupportedCAM_DC1394(pcap->format, preferred_modes[i], modes[format_idx]) ){
279             pcap->mode = preferred_modes[i];
280         }
281     }
282     if (pcap->mode == 0) {
283         fprintf(stderr,"%s:%d: Could not find a supported mode for this camera\n",__FILE__,__LINE__);
284         goto ERROR;
285     }
286 
287     pcap->color_mode = icvColorMode( pcap->mode );
288     if( pcap->color_mode == -1){
289         fprintf(stderr,"%s:%d: ERROR: BPP is Unsupported!!\n",__FILE__,__LINE__);
290         goto ERROR;
291     }
292 
293     // set frame rate to optimal value given format and mode
294     pcap->frame_rate = icvGetBestFrameRate(pcap, pcap->format, pcap->mode);
295 
296     if (pcap->format!=FORMAT_SCALABLE_IMAGE_SIZE) { // everything except Format 7
297         if (dc1394_dma_setup_capture(pcap->handle, pcap->camera->node, index+1 /*channel*/,
298                     pcap->format, pcap->mode, SPEED_400,
299                     pcap->frame_rate, NUM_BUFFERS, 1 /*drop_frames*/,
300                     pcap->device_name, pcap->camera) != DC1394_SUCCESS) {
301             fprintf(stderr,"%s:%d: Failed to setup DMA capture with VIDEO1394\n",__FILE__,__LINE__);
302             goto ERROR;
303         }
304     }
305     else {
306         if(dc1394_dma_setup_format7_capture(pcap->handle,pcap->camera->node,index+1 /*channel*/,
307                     pcap->mode, SPEED_400, QUERY_FROM_CAMERA,
308                     (unsigned int)QUERY_FROM_CAMERA, (unsigned int)QUERY_FROM_CAMERA,
309                     (unsigned int)QUERY_FROM_CAMERA, (unsigned int)QUERY_FROM_CAMERA,
310                     NUM_BUFFERS, 1 /*drop_frames*/,
311                     pcap->device_name, pcap->camera) != DC1394_SUCCESS) {
312             fprintf(stderr,"%s:%d: Failed to setup DMA capture with VIDEO1394\n",__FILE__,__LINE__);
313             goto ERROR;
314         }
315     }
316 
317     if (dc1394_start_iso_transmission(pcap->handle, pcap->camera->node)!=DC1394_SUCCESS) {
318         fprintf(stderr,"%s:%d: Could not start ISO transmission\n",__FILE__,__LINE__);
319         goto ERROR;
320     }
321 
322     usleep(DELAY);
323 
324     dc1394bool_t status;
325     if (dc1394_get_iso_status(pcap->handle, pcap->camera->node, &status)!=DC1394_SUCCESS) {
326         fprintf(stderr,"%s:%d: Could get ISO status",__FILE__,__LINE__);
327         goto ERROR;
328     }
329     if (status==DC1394_FALSE) {
330         fprintf(stderr,"%s:%d: ISO transmission refuses to start",__FILE__,__LINE__);
331         goto ERROR;
332     }
333 
334     // convert camera image to RGB by default
335     pcap->convert=1;
336 
337     // no image data allocated yet
338     pcap->buffer_is_writeable = 0;
339 
340     memset(&(pcap->frame), 0, sizeof(IplImage));
341     icvResizeFrame( pcap );
342     return pcap;
343 
344 ERROR:
345     return 0;
346 };
347 
icvCloseCAM_DC1394(CvCaptureCAM_DC1394 * capture)348 static void icvCloseCAM_DC1394( CvCaptureCAM_DC1394* capture ){
349     dc1394_stop_iso_transmission(capture->handle, capture->camera->node);
350     dc1394_dma_unlisten (capture->handle, capture->camera);
351     /* Deallocate space for RGBA data */
352     if(capture->convert){
353         cvFree(&capture->frame.imageData);
354     }
355 }
356 
icvGrabFrameCAM_DC1394(CvCaptureCAM_DC1394 * capture)357 static int icvGrabFrameCAM_DC1394( CvCaptureCAM_DC1394* capture ){
358     // TODO: should this function wait until the next frame is available or return
359     // immediately ?
360     float waiting = 0;
361     do{
362         int result = dc1394_dma_single_capture_poll(capture->camera);
363         if(result==DC1394_SUCCESS){
364             return 1;
365         }
366         else if(result==DC1394_NO_FRAME){
367             usleep(1000000/120);  //sleep for at least a 1/2 of the frame rate
368             waiting += 1.0/120.0;
369         }
370         else{
371             printf("dc1394_dma_single_capture_poll failed\n");
372             return 0;
373         }
374     } while(waiting<2);
375     printf("dc1394_dma_single_capture_poll timed out\n");
376     return 0;
377 }
378 
icvRetrieveFrameCAM_DC1394(CvCaptureCAM_DC1394 * capture,int)379 static IplImage* icvRetrieveFrameCAM_DC1394( CvCaptureCAM_DC1394* capture, int ){
380     if(capture->camera->capture_buffer )
381     {
382         if(capture->convert){
383             /* Convert to RGBA */
384             unsigned char * src = (unsigned char *)capture->camera->capture_buffer;
385             unsigned char * dst = (unsigned char *)capture->frame.imageData;
386             switch (capture->color_mode) {
387                 case COLOR_FORMAT7_RGB8:
388                     //printf("icvRetrieveFrame convert RGB to BGR\n");
389                     /* Convert RGB to BGR */
390                     for (int i=0;i<capture->frame.imageSize;i+=6) {
391                         dst[i]   = src[i+2];
392                         dst[i+1] = src[i+1];
393                         dst[i+2] = src[i];
394                         dst[i+3] = src[i+5];
395                         dst[i+4] = src[i+4];
396                         dst[i+5] = src[i+3];
397                     }
398                     break;
399                 case COLOR_FORMAT7_YUV422:
400                     //printf("icvRetrieveFrame convert YUV422 to BGR %d\n");
401                     uyvy2bgr(src,
402                             dst,
403                             capture->camera->frame_width * capture->camera->frame_height);
404                     break;
405                 case COLOR_FORMAT7_MONO8:
406                     //printf("icvRetrieveFrame convert MONO8 to BGR %d\n");
407                     y2bgr(src,
408                             dst,
409                             capture->camera->frame_width * capture->camera->frame_height);
410                     break;
411                 case COLOR_FORMAT7_YUV411:
412                     //printf("icvRetrieveFrame convert YUV411 to BGR %d\n");
413                     uyyvyy2bgr(src,
414                             dst,
415                             capture->camera->frame_width * capture->camera->frame_height);
416                     break;
417                 case COLOR_FORMAT7_YUV444:
418                     //printf("icvRetrieveFrame convert YUV444 to BGR %d\n");
419                     uyv2bgr(src,
420                             dst,
421                             capture->camera->frame_width * capture->camera->frame_height);
422                     break;
423                 case COLOR_FORMAT7_MONO16:
424                     //printf("icvRetrieveFrame convert MONO16 to BGR %d\n");
425                     y162bgr(src,
426                             dst,
427                             capture->camera->frame_width * capture->camera->frame_height, MONO16_BPP);
428                     break;
429                 case COLOR_FORMAT7_RGB16:
430                     //printf("icvRetrieveFrame convert RGB16 to BGR %d\n");
431                     rgb482bgr(src,
432                             dst,
433                             capture->camera->frame_width * capture->camera->frame_height, MONO16_BPP);
434                     break;
435                 default:
436                     fprintf(stderr,"%s:%d: Unsupported color mode %d\n",__FILE__,__LINE__,capture->color_mode);
437                     return 0;
438             } /* switch (capture->mode) */
439         }
440         else{
441             // return raw data
442             capture->frame.imageData = (char *) capture->camera->capture_buffer;
443             capture->frame.imageDataOrigin = (char *) capture->camera->capture_buffer;
444         }
445 
446         // TODO: if convert=0, we are not actually done with the buffer
447         // but this seems to work anyway.
448         dc1394_dma_done_with_buffer(capture->camera);
449 
450         return &capture->frame;
451     }
452     return 0;
453 };
454 
icvGetPropertyCAM_DC1394(CvCaptureCAM_DC1394 * capture,int property_id)455 static double icvGetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id ){
456     int index=-1;
457     switch ( property_id ) {
458         case CV_CAP_PROP_CONVERT_RGB:
459             return capture->convert;
460         case CV_CAP_PROP_MODE:
461             return capture->mode;
462         case CV_CAP_PROP_FORMAT:
463             return capture->format;
464         case CV_CAP_PROP_FPS:
465             CV_DC1394_CALL(dc1394_get_video_framerate(capture->handle, capture->camera->node,
466                     (unsigned int *) &capture->camera->frame_rate));
467             switch(capture->camera->frame_rate) {
468                 case FRAMERATE_1_875:
469                     return 1.875;
470                 case FRAMERATE_3_75:
471                     return 3.75;
472                 case FRAMERATE_7_5:
473                     return 7.5;
474                 case FRAMERATE_15:
475                     return 15.;
476                 case FRAMERATE_30:
477                     return 30.;
478                 case FRAMERATE_60:
479                     return 60;
480 #if NUM_FRAMERATES > 6
481                 case FRAMERATE_120:
482                     return 120;
483 #endif
484 #if NUM_FRAMERATES > 7
485                 case FRAMERATE_240:
486                     return 240;
487 #endif
488             }
489         default:
490             index = property_id;  // did they pass in a LIBDC1394 feature flag?
491             break;
492     }
493     if(index>=FEATURE_MIN && index<=FEATURE_MAX){
494         dc1394bool_t has_feature;
495         CV_DC1394_CALL( dc1394_is_feature_present(capture->handle, capture->camera->node,
496                                                   index, &has_feature));
497         if(!has_feature){
498             CV_WARN("Feature is not supported by this camera");
499         }
500         else{
501             unsigned int value;
502             dc1394_get_feature_value(capture->handle, capture->camera->node, index, &value);
503             return (double) value;
504         }
505     }
506 
507     return 0;
508 };
509 
510 // resize capture->frame appropriately depending on camera and capture settings
icvResizeFrame(CvCaptureCAM_DC1394 * capture)511 static int icvResizeFrame(CvCaptureCAM_DC1394 * capture){
512     if(capture->convert){
513         // resize if sizes are different, formats are different
514         // or conversion option has changed
515         if(capture->camera->frame_width != capture->frame.width ||
516            capture->camera->frame_height != capture->frame.height ||
517            capture->frame.depth != 8 ||
518            capture->frame.nChannels != 3 ||
519            capture->frame.imageData == NULL ||
520            capture->buffer_is_writeable == 0)
521         {
522             if(capture->frame.imageData && capture->buffer_is_writeable){
523                 cvReleaseData( &(capture->frame));
524             }
525             cvInitImageHeader( &capture->frame, cvSize( capture->camera->frame_width,
526                                                         capture->camera->frame_height ),
527                                 IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 );
528             cvCreateData( &(capture->frame) );
529             capture->buffer_is_writeable = 1;
530         }
531 
532     }
533     else {
534         // free image data if allocated by opencv
535         if(capture->buffer_is_writeable){
536             cvReleaseData(&(capture->frame));
537         }
538 
539         // figure out number of channels and bpp
540         int bpp = 8;
541         int nch = 3;
542         int width = capture->camera->frame_width;
543         int height = capture->camera->frame_height;
544         double code = CV_FOURCC('B','G','R',0);
545         switch(capture->color_mode){
546         case COLOR_FORMAT7_YUV422:
547             nch = 2;
548             code = CV_FOURCC('Y','4','2','2');
549             break;
550         case COLOR_FORMAT7_MONO8:
551             code = CV_FOURCC('Y',0,0,0);
552             nch = 1;
553             break;
554         case COLOR_FORMAT7_YUV411:
555             code = CV_FOURCC('Y','4','1','1');
556             width *= 2;
557             nch = 3;  //yy[u/v]
558             break;
559         case COLOR_FORMAT7_YUV444:
560             code = CV_FOURCC('Y','U','V',0);
561             nch = 3;
562             break;
563         case COLOR_FORMAT7_MONO16:
564             code = CV_FOURCC('Y',0,0,0);
565             bpp = IPL_DEPTH_16S;
566             nch = 1;
567             break;
568         case COLOR_FORMAT7_RGB16:
569             bpp = IPL_DEPTH_16S;
570             nch = 3;
571             break;
572         default:
573             break;
574         }
575         // reset image header
576         cvInitImageHeader( &capture->frame,cvSize( width, height ), bpp, nch, IPL_ORIGIN_TL, 4 );
577         //assert(capture->frame.imageSize == capture->camera->quadlets_per_frame*4);
578         capture->buffer_is_writeable = 0;
579     }
580     return 1;
581 }
582 
583 // Toggle setting about whether or not RGB color conversion is to be performed
584 // Allocates/Initializes capture->frame appropriately
icvSetConvertRGB(CvCaptureCAM_DC1394 * capture,int convert)585 int icvSetConvertRGB(CvCaptureCAM_DC1394 * capture, int convert){
586     if(convert==capture->convert){
587         // no action necessary
588         return 1;
589     }
590     capture->convert = convert;
591     return icvResizeFrame( capture );
592 }
593 
594 // given desired format, mode, and modes bitmask from camera, determine if format and mode are supported
595 static int
icvFormatSupportedCAM_DC1394(int format,quadlet_t formats)596 icvFormatSupportedCAM_DC1394(int format, quadlet_t formats){
597     // formats is a bitmask whose higher order bits indicate whether format is supported
598     int shift = 31 - (format - FORMAT_MIN);
599     int mask = 1 << shift;
600     return (formats & mask) != 0;
601 }
602 
603 // analyze modes bitmask from camera to determine if desired format and mode are supported
604 static int
icvModeSupportedCAM_DC1394(int format,int mode,quadlet_t modes)605 icvModeSupportedCAM_DC1394(int format, int mode, quadlet_t modes){
606     // modes is a bitmask whose higher order bits indicate whether mode is supported
607     int format_idx = format - FORMAT_MIN;
608     int mode_format_min = MODE_FORMAT0_MIN + 32*format_idx;
609     int shift = 31 - (mode - mode_format_min);
610     int mask = 0x1 << shift;
611     return (modes & mask) != 0;
612 }
613 
614 // Setup camera to use given dc1394 mode
615 static int
icvSetModeCAM_DC1394(CvCaptureCAM_DC1394 * capture,int mode)616 icvSetModeCAM_DC1394( CvCaptureCAM_DC1394 * capture, int mode ){
617     quadlet_t modes, formats;
618     //printf("<icvSetModeCAM_DC1394>\n");
619 
620     // figure out corrent format for this mode
621     int format = (mode - MODE_FORMAT0_MIN) / 32 + FORMAT_MIN;
622 
623     // get supported formats
624     if (dc1394_query_supported_formats(capture->handle, capture->camera->node, &formats)<0) {
625         fprintf(stderr,"%s:%d: Could not query supported formats\n",__FILE__,__LINE__);
626         return 0;
627     }
628 
629     // is format for requested mode supported ?
630     if(icvFormatSupportedCAM_DC1394(format, formats)==0){
631         return 0;
632     }
633 
634     // get supported modes for requested format
635     if (dc1394_query_supported_modes(capture->handle, capture->camera->node, format, &modes)<0){
636         fprintf(stderr,"%s:%d: Could not query supported modes for format %d\n",__FILE__,__LINE__, capture->format);
637         return 0;
638     }
639 
640     // is requested mode supported ?
641     if(! icvModeSupportedCAM_DC1394(format, mode, modes) ){
642         return 0;
643     }
644 
645     int color_mode = icvColorMode( mode );
646 
647     if(color_mode == -1){
648         return 0;
649     }
650 
651     int frame_rate = icvGetBestFrameRate(capture, format, mode);
652 
653     dc1394_dma_unlisten(capture->handle, capture->camera);
654     if (dc1394_dma_setup_capture(capture->handle, capture->camera->node, capture->camera->channel /*channel*/,
655                 format, mode, SPEED_400,
656                 frame_rate, NUM_BUFFERS, 1 /*drop_frames*/,
657                 capture->device_name, capture->camera) != DC1394_SUCCESS) {
658         fprintf(stderr,"%s:%d: Failed to setup DMA capture with VIDEO1394\n",__FILE__,__LINE__);
659         return 0;
660     }
661     dc1394_start_iso_transmission(capture->handle, capture->camera->node);
662 
663     capture->frame_rate = frame_rate;
664     capture->format = format;
665     capture->mode = mode;
666     capture->color_mode = color_mode;
667 
668     // now fix image size to match new mode
669     icvResizeFrame( capture );
670     return 1;
671 }
672 
673 // query camera for supported frame rates and select fastest for given format and mode
icvGetBestFrameRate(CvCaptureCAM_DC1394 * capture,int format,int mode)674 static unsigned int icvGetBestFrameRate( CvCaptureCAM_DC1394 * capture, int format, int mode  ){
675     quadlet_t framerates;
676     if (dc1394_query_supported_framerates(capture->handle, capture->camera->node,
677                 format, mode, &framerates)!=DC1394_SUCCESS)
678     {
679         fprintf(stderr,"%s:%d: Could not query supported framerates\n",__FILE__,__LINE__);
680         framerates = 0;
681     }
682 
683     for (int f=FRAMERATE_MAX; f>=FRAMERATE_MIN; f--) {
684         if (framerates & (0x1<< (31-(f-FRAMERATE_MIN)))) {
685             return f;
686         }
687     }
688     return 0;
689 }
690 
691 static int
icvSetFrameRateCAM_DC1394(CvCaptureCAM_DC1394 * capture,double value)692 icvSetFrameRateCAM_DC1394( CvCaptureCAM_DC1394 * capture, double value ){
693     unsigned int fps=15;
694     if(capture->format == FORMAT_SCALABLE_IMAGE_SIZE)
695         return 0; /* format 7 has no fixed framerates */
696     if (value==-1){
697         fps=icvGetBestFrameRate( capture, capture->format, capture->mode );
698     }
699     else if (value==1.875)
700         fps=FRAMERATE_1_875;
701     else if (value==3.75)
702         fps=FRAMERATE_3_75;
703     else if (value==7.5)
704         fps=FRAMERATE_7_5;
705     else if (value==15)
706         fps=FRAMERATE_15;
707     else if (value==30)
708         fps=FRAMERATE_30;
709     else if (value==60)
710         fps=FRAMERATE_60;
711 #if NUM_FRAMERATES > 6
712     else if (value==120)
713         fps=FRAMERATE_120;
714 #endif
715 #if NUM_FRAMERATES > 7
716     else if (value==240)
717         fps=FRAMERATE_240;
718 #endif
719     dc1394_set_video_framerate(capture->handle, capture->camera->node,fps);
720     dc1394_get_video_framerate(capture->handle, capture->camera->node,
721                     (unsigned int *) &capture->camera->frame_rate);
722 
723     return fps==(unsigned int) capture->camera->frame_rate;
724 }
725 
726 // for given mode return color format
727 static int
icvColorMode(int mode)728 icvColorMode( int mode ){
729     switch(mode) {
730     case MODE_160x120_YUV444:
731         return COLOR_FORMAT7_YUV444;
732     case MODE_320x240_YUV422:
733     case MODE_640x480_YUV422:
734     case MODE_800x600_YUV422:
735     case MODE_1024x768_YUV422:
736     case MODE_1280x960_YUV422:
737     case MODE_1600x1200_YUV422:
738         return COLOR_FORMAT7_YUV422;
739     case MODE_640x480_YUV411:
740         return COLOR_FORMAT7_YUV411;
741     case MODE_640x480_RGB:
742     case MODE_800x600_RGB:
743     case MODE_1024x768_RGB:
744     case MODE_1280x960_RGB:
745     case MODE_1600x1200_RGB:
746         return COLOR_FORMAT7_RGB8;
747     case MODE_640x480_MONO:
748     case MODE_800x600_MONO:
749     case MODE_1024x768_MONO:
750     case MODE_1280x960_MONO:
751     case MODE_1600x1200_MONO:
752         return COLOR_FORMAT7_MONO8;
753     case MODE_640x480_MONO16:
754     case MODE_800x600_MONO16:
755     case MODE_1024x768_MONO16:
756     case MODE_1280x960_MONO16:
757     case MODE_1600x1200_MONO16:
758         return COLOR_FORMAT7_MONO16;
759     case MODE_FORMAT7_0:
760     case MODE_FORMAT7_1:
761     case MODE_FORMAT7_2:
762     case MODE_FORMAT7_3:
763     case MODE_FORMAT7_4:
764     case MODE_FORMAT7_5:
765     case MODE_FORMAT7_6:
766     case MODE_FORMAT7_7:
767         fprintf(stderr,"%s:%d: Format7 not yet supported\n",__FILE__,__LINE__);
768     default:
769         break;
770     }
771     return -1;
772 }
773 
774 // function to set camera properties using dc1394 feature enum
775 // val == -1 indicates to set this property to 'auto'
776 static int
icvSetFeatureCAM_DC1394(CvCaptureCAM_DC1394 * capture,int feature_id,int val)777 icvSetFeatureCAM_DC1394( CvCaptureCAM_DC1394* capture, int feature_id, int val){
778         dc1394bool_t isOn = DC1394_FALSE;
779         dc1394bool_t hasAutoCapability = DC1394_FALSE;
780         dc1394bool_t isAutoOn = DC1394_FALSE;
781         unsigned int nval;
782         unsigned int minval,maxval;
783 
784         // Turn the feature on if it is OFF
785         if( dc1394_is_feature_on(capture->handle, capture->camera->node, feature_id, &isOn)
786                 == DC1394_FAILURE ) {
787             return 0;
788         }
789         if( isOn == DC1394_FALSE ) {
790                 // try to turn it on.
791                 if( dc1394_feature_on_off(capture->handle, capture->camera->node, feature_id, 1) == DC1394_FAILURE ) {
792                     fprintf(stderr, "error turning feature %d on!\n", feature_id);
793                     return 0;
794                 }
795         }
796 
797         // Check if the feature supports auto mode
798         dc1394_has_auto_mode(capture->handle, capture->camera->node, feature_id, &hasAutoCapability);
799         if( hasAutoCapability ) {
800 
801             // now check if the auto is on.
802             if( dc1394_is_feature_auto(capture->handle, capture->camera->node, feature_id, &isAutoOn ) == DC1394_FAILURE ) {
803                 fprintf(stderr, "error determining if feature %d has auto on!\n", feature_id);
804                 return 0;
805             }
806         }
807         // Caller requested auto mode, but cannot support it
808         else if(val==-1){
809             fprintf(stderr, "feature %d does not support auto mode\n", feature_id);
810             return 0;
811         }
812 
813         if(val==-1){
814             // if the auto mode isn't enabled, enable it
815             if( isAutoOn == DC1394_FALSE ) {
816                 if(dc1394_auto_on_off(capture->handle, capture->camera->node, feature_id, 1) == DC1394_FAILURE ) {
817                     fprintf(stderr, "error turning feature %d auto ON!\n", feature_id);
818                     return 0;
819                 }
820             }
821             return 1;
822         }
823 
824         // ELSE turn OFF auto and adjust feature manually
825         if( isAutoOn == DC1394_TRUE ) {
826             if(dc1394_auto_on_off(capture->handle, capture->camera->node, feature_id, 0) == DC1394_FAILURE ) {
827                 fprintf(stderr, "error turning feature %d auto OFF!\n", feature_id);
828                 return 0;
829             }
830         }
831 
832         // Clamp val to within feature range
833         CV_DC1394_CALL(	dc1394_get_min_value(capture->handle, capture->camera->node, feature_id, &minval));
834         CV_DC1394_CALL(	dc1394_get_max_value(capture->handle, capture->camera->node, feature_id, &maxval));
835         val = (int)MIN(maxval, MAX((unsigned)val, minval));
836 
837 
838         if (dc1394_set_feature_value(capture->handle, capture->camera->node, feature_id, val) ==
839                 DC1394_FAILURE){
840             fprintf(stderr, "error setting feature value\n");
841             return 0;
842         }
843         if (dc1394_get_feature_value(capture->handle, capture->camera->node, feature_id, &nval) ==
844                 DC1394_FAILURE){
845             fprintf(stderr, "error setting feature value\n");
846             return 0;
847         }
848         return nval==(unsigned int)val;
849 
850 }
851 
852 // cvSetCaptureProperty callback function implementation
853 static int
icvSetPropertyCAM_DC1394(CvCaptureCAM_DC1394 * capture,int property_id,double value)854 icvSetPropertyCAM_DC1394( CvCaptureCAM_DC1394* capture, int property_id, double value ){
855     int index=-1;
856     switch ( property_id ) {
857         case CV_CAP_PROP_CONVERT_RGB:
858             return icvSetConvertRGB( capture, value != 0 );
859         case CV_CAP_PROP_MODE:
860             return icvSetModeCAM_DC1394( capture, (int) value );
861         case CV_CAP_PROP_FPS:
862             return icvSetFrameRateCAM_DC1394( capture, value );
863         case CV_CAP_PROP_BRIGHTNESS:
864             index = FEATURE_BRIGHTNESS;
865             break;
866         case CV_CAP_PROP_CONTRAST:
867             index = FEATURE_GAMMA;
868             break;
869         case CV_CAP_PROP_SATURATION:
870             index = FEATURE_SATURATION;
871             break;
872         case CV_CAP_PROP_HUE:
873             index = FEATURE_HUE;
874             break;
875         case CV_CAP_PROP_GAIN:
876             index = FEATURE_GAIN;
877             break;
878         default:
879             index = property_id;  // did they pass in a LIBDC1394 feature flag?
880             break;
881     }
882     if(index>=FEATURE_MIN && index<=FEATURE_MAX){
883         return icvSetFeatureCAM_DC1394(capture, index, (int) value);
884     }
885     return 0;
886 };
887 
888 /**********************************************************************
889  *
890  *  CONVERSION FUNCTIONS TO RGB 24bpp
891  *
892  **********************************************************************/
893 
894 /* color conversion functions from Bart Nabbe. *//* corrected by Damien: bad coeficients in YUV2RGB */
895 #define YUV2RGB(y, u, v, r, g, b)\
896     r = y + ((v*1436) >> 10);\
897 g = y - ((u*352 + v*731) >> 10);\
898 b = y + ((u*1814) >> 10);\
899 r = r < 0 ? 0 : r;\
900 g = g < 0 ? 0 : g;\
901 b = b < 0 ? 0 : b;\
902 r = r > 255 ? 255 : r;\
903 g = g > 255 ? 255 : g;\
904 b = b > 255 ? 255 : b
905 
906     static void
uyv2bgr(const unsigned char * src,unsigned char * dest,unsigned long long int NumPixels)907 uyv2bgr(const unsigned char *src, unsigned char *dest,
908         unsigned long long int NumPixels)
909 {
910     register int i = NumPixels + (NumPixels << 1) - 1;
911     register int j = NumPixels + (NumPixels << 1) - 1;
912     register int y, u, v;
913     register int r, g, b;
914 
915     while (i > 0) {
916         v = src[i--] - 128;
917         y = src[i--];
918         u = src[i--] - 128;
919         YUV2RGB(y, u, v, r, g, b);
920         dest[j--] = r;
921         dest[j--] = g;
922         dest[j--] = b;
923     }
924 }
925 
926     static void
uyvy2bgr(const unsigned char * src,unsigned char * dest,unsigned long long int NumPixels)927 uyvy2bgr(const unsigned char *src, unsigned char *dest,
928         unsigned long long int NumPixels)
929 {
930     register int i = (NumPixels << 1) - 1;
931     register int j = NumPixels + (NumPixels << 1) - 1;
932     register int y0, y1, u, v;
933     register int r, g, b;
934 
935     while (i > 0) {
936         y1 = src[i--];
937         v = src[i--] - 128;
938         y0 = src[i--];
939         u = src[i--] - 128;
940         YUV2RGB(y1, u, v, r, g, b);
941         dest[j--] = r;
942         dest[j--] = g;
943         dest[j--] = b;
944         YUV2RGB(y0, u, v, r, g, b);
945         dest[j--] = r;
946         dest[j--] = g;
947         dest[j--] = b;
948     }
949 }
950 
951 
952     static void
uyyvyy2bgr(const unsigned char * src,unsigned char * dest,unsigned long long int NumPixels)953 uyyvyy2bgr(const unsigned char *src, unsigned char *dest,
954         unsigned long long int NumPixels)
955 {
956     register int i = NumPixels + (NumPixels >> 1) - 1;
957     register int j = NumPixels + (NumPixels << 1) - 1;
958     register int y0, y1, y2, y3, u, v;
959     register int r, g, b;
960 
961     while (i > 0) {
962         y3 = src[i--];
963         y2 = src[i--];
964         v = src[i--] - 128;
965         y1 = src[i--];
966         y0 = src[i--];
967         u = src[i--] - 128;
968         YUV2RGB(y3, u, v, r, g, b);
969         dest[j--] = r;
970         dest[j--] = g;
971         dest[j--] = b;
972         YUV2RGB(y2, u, v, r, g, b);
973         dest[j--] = r;
974         dest[j--] = g;
975         dest[j--] = b;
976         YUV2RGB(y1, u, v, r, g, b);
977         dest[j--] = r;
978         dest[j--] = g;
979         dest[j--] = b;
980         YUV2RGB(y0, u, v, r, g, b);
981         dest[j--] = r;
982         dest[j--] = g;
983         dest[j--] = b;
984     }
985 }
986 
987     static void
y2bgr(const unsigned char * src,unsigned char * dest,unsigned long long int NumPixels)988 y2bgr(const unsigned char *src, unsigned char *dest,
989         unsigned long long int NumPixels)
990 {
991     register int i = NumPixels - 1;
992     register int j = NumPixels + (NumPixels << 1) - 1;
993     register int y;
994 
995     while (i > 0) {
996         y = src[i--];
997         dest[j--] = y;
998         dest[j--] = y;
999         dest[j--] = y;
1000     }
1001 }
1002 
1003     static void
y162bgr(const unsigned char * src,unsigned char * dest,unsigned long long int NumPixels,int bits)1004 y162bgr(const unsigned char *src, unsigned char *dest,
1005         unsigned long long int NumPixels, int bits)
1006 {
1007     register int i = (NumPixels << 1) - 1;
1008     register int j = NumPixels + (NumPixels << 1) - 1;
1009     register int y;
1010 
1011     while (i > 0) {
1012         y = src[i--];
1013         y = (y + (src[i--] << 8)) >> (bits - 8);
1014         dest[j--] = y;
1015         dest[j--] = y;
1016         dest[j--] = y;
1017     }
1018 }
1019 
1020 // this one was in coriander but didn't take bits into account
1021     static void
rgb482bgr(const unsigned char * src,unsigned char * dest,unsigned long long int NumPixels,int bits)1022 rgb482bgr(const unsigned char *src, unsigned char *dest,
1023         unsigned long long int NumPixels, int bits)
1024 {
1025     register int i = (NumPixels << 1) - 1;
1026     register int j = NumPixels + (NumPixels << 1) - 1;
1027     register int y;
1028 
1029     while (i > 0) {
1030         y = src[i--];
1031         dest[j-2] = (y + (src[i--] << 8)) >> (bits - 8);
1032         j--;
1033         y = src[i--];
1034         dest[j] = (y + (src[i--] << 8)) >> (bits - 8);
1035         j--;
1036         y = src[i--];
1037         dest[j+2] = (y + (src[i--] << 8)) >> (bits - 8);
1038         j--;
1039     }
1040 }
1041 
1042 
1043 class CvCaptureCAM_DC1394_CPP : public CvCapture
1044 {
1045 public:
CvCaptureCAM_DC1394_CPP()1046     CvCaptureCAM_DC1394_CPP() { captureDC1394 = 0; }
~CvCaptureCAM_DC1394_CPP()1047     virtual ~CvCaptureCAM_DC1394_CPP() { close(); }
1048 
1049     virtual bool open( int index );
1050     virtual void close();
1051 
1052     virtual double getProperty(int) const;
1053     virtual bool setProperty(int, double);
1054     virtual bool grabFrame();
1055     virtual IplImage* retrieveFrame(int);
getCaptureDomain()1056     virtual int getCaptureDomain() { return CV_CAP_DC1394; } // Return the type of the capture object: CV_CAP_VFW, etc...
1057 protected:
1058 
1059     CvCaptureCAM_DC1394* captureDC1394;
1060 };
1061 
open(int index)1062 bool CvCaptureCAM_DC1394_CPP::open( int index )
1063 {
1064     close();
1065     captureDC1394 = icvCaptureFromCAM_DC1394(index);
1066     return captureDC1394 != 0;
1067 }
1068 
close()1069 void CvCaptureCAM_DC1394_CPP::close()
1070 {
1071     if( captureDC1394 )
1072     {
1073         icvCloseCAM_DC1394( captureDC1394 );
1074         cvFree( &captureDC1394 );
1075     }
1076 }
1077 
grabFrame()1078 bool CvCaptureCAM_DC1394_CPP::grabFrame()
1079 {
1080     return captureDC1394 ? icvGrabFrameCAM_DC1394( captureDC1394 ) != 0 : false;
1081 }
1082 
retrieveFrame(int)1083 IplImage* CvCaptureCAM_DC1394_CPP::retrieveFrame(int)
1084 {
1085     return captureDC1394 ? (IplImage*)icvRetrieveFrameCAM_DC1394( captureDC1394, 0 ) : 0;
1086 }
1087 
getProperty(int propId) const1088 double CvCaptureCAM_DC1394_CPP::getProperty( int propId ) const
1089 {
1090     // Simulate mutable (C++11-like) member variable
1091     // (some members are used to cache property settings).
1092     CvCaptureCAM_DC1394* cap = const_cast<CvCaptureCAM_DC1394*>(captureDC1394);
1093 
1094     return cap ? icvGetPropertyCAM_DC1394( cap, propId ) : 0;
1095 }
1096 
setProperty(int propId,double value)1097 bool CvCaptureCAM_DC1394_CPP::setProperty( int propId, double value )
1098 {
1099     return captureDC1394 ? icvSetPropertyCAM_DC1394( captureDC1394, propId, value ) != 0 : false;
1100 }
1101 
cvCreateCameraCapture_DC1394(int index)1102 CvCapture* cvCreateCameraCapture_DC1394( int index )
1103 {
1104     CvCaptureCAM_DC1394_CPP* capture = new CvCaptureCAM_DC1394_CPP;
1105 
1106     if( capture->open( index ))
1107         return capture;
1108 
1109     delete capture;
1110     return 0;
1111 }
1112 
1113 #endif
1114