Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videoio/src/cap_dc1394.cpp
16354 views
1
/* This is the contributed code:
2
Firewire and video4linux camera support for videoio
3
4
2003-03-12 Magnus Lundin
5
[email protected]
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
[email protected]
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
907
uyv2bgr(const unsigned char *src, unsigned char *dest,
908
unsigned long long int NumPixels)
909
{
910
int i = NumPixels + (NumPixels << 1) - 1;
911
int j = NumPixels + (NumPixels << 1) - 1;
912
int y, u, v;
913
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
927
uyvy2bgr(const unsigned char *src, unsigned char *dest,
928
unsigned long long int NumPixels)
929
{
930
int i = (NumPixels << 1) - 1;
931
int j = NumPixels + (NumPixels << 1) - 1;
932
int y0, y1, u, v;
933
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
953
uyyvyy2bgr(const unsigned char *src, unsigned char *dest,
954
unsigned long long int NumPixels)
955
{
956
int i = NumPixels + (NumPixels >> 1) - 1;
957
int j = NumPixels + (NumPixels << 1) - 1;
958
int y0, y1, y2, y3, u, v;
959
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
988
y2bgr(const unsigned char *src, unsigned char *dest,
989
unsigned long long int NumPixels)
990
{
991
int i = NumPixels - 1;
992
int j = NumPixels + (NumPixels << 1) - 1;
993
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
1004
y162bgr(const unsigned char *src, unsigned char *dest,
1005
unsigned long long int NumPixels, int bits)
1006
{
1007
int i = (NumPixels << 1) - 1;
1008
int j = NumPixels + (NumPixels << 1) - 1;
1009
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
1022
rgb482bgr(const unsigned char *src, unsigned char *dest,
1023
unsigned long long int NumPixels, int bits)
1024
{
1025
int i = (NumPixels << 1) - 1;
1026
int j = NumPixels + (NumPixels << 1) - 1;
1027
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:
1046
CvCaptureCAM_DC1394_CPP() { captureDC1394 = 0; }
1047
virtual ~CvCaptureCAM_DC1394_CPP() { close(); }
1048
1049
virtual bool open( int index );
1050
virtual void close();
1051
1052
virtual double getProperty(int) const CV_OVERRIDE;
1053
virtual bool setProperty(int, double) CV_OVERRIDE;
1054
virtual bool grabFrame() CV_OVERRIDE;
1055
virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
1056
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_DC1394; }
1057
protected:
1058
1059
CvCaptureCAM_DC1394* captureDC1394;
1060
};
1061
1062
bool CvCaptureCAM_DC1394_CPP::open( int index )
1063
{
1064
close();
1065
captureDC1394 = icvCaptureFromCAM_DC1394(index);
1066
return captureDC1394 != 0;
1067
}
1068
1069
void CvCaptureCAM_DC1394_CPP::close()
1070
{
1071
if( captureDC1394 )
1072
{
1073
icvCloseCAM_DC1394( captureDC1394 );
1074
cvFree( &captureDC1394 );
1075
}
1076
}
1077
1078
bool CvCaptureCAM_DC1394_CPP::grabFrame()
1079
{
1080
return captureDC1394 ? icvGrabFrameCAM_DC1394( captureDC1394 ) != 0 : false;
1081
}
1082
1083
IplImage* CvCaptureCAM_DC1394_CPP::retrieveFrame(int)
1084
{
1085
return captureDC1394 ? (IplImage*)icvRetrieveFrameCAM_DC1394( captureDC1394, 0 ) : 0;
1086
}
1087
1088
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
1097
bool CvCaptureCAM_DC1394_CPP::setProperty( int propId, double value )
1098
{
1099
return captureDC1394 ? icvSetPropertyCAM_DC1394( captureDC1394, propId, value ) != 0 : false;
1100
}
1101
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
1115