1 | /*M/////////////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
4 | // |
5 | // By downloading, copying, installing or using the software you agree to this license. |
6 | // If you do not agree to this license, do not download, install, |
7 | // copy or use the software. |
8 | // |
9 | // |
10 | // Intel License Agreement |
11 | // For Open Source Computer Vision Library |
12 | // |
13 | // Copyright (C) 2000, Intel Corporation, all rights reserved. |
14 | // Third party copyrights are property of their respective owners. |
15 | // |
16 | // Redistribution and use in source and binary forms, with or without modification, |
17 | // are permitted provided that the following conditions are met: |
18 | // |
19 | // * Redistribution's of source code must retain the above copyright notice, |
20 | // this list of conditions and the following disclaimer. |
21 | // |
22 | // * Redistribution's in binary form must reproduce the above copyright notice, |
23 | // this list of conditions and the following disclaimer in the documentation |
24 | // and/or other materials provided with the distribution. |
25 | // |
26 | // * The name of Intel Corporation may not be used to endorse or promote products |
27 | // derived from this software without specific prior written permission. |
28 | // |
29 | // This software is provided by the copyright holders and contributors "as is" and |
30 | // any express or implied warranties, including, but not limited to, the implied |
31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. |
32 | // In no event shall the Intel Corporation or contributors be liable for any direct, |
33 | // indirect, incidental, special, exemplary, or consequential damages |
34 | // (including, but not limited to, procurement of substitute goods or services; |
35 | // loss of use, data, or profits; or business interruption) however caused |
36 | // and on any theory of liability, whether in contract, strict liability, |
37 | // or tort (including negligence or otherwise) arising in any way out of |
38 | // the use of this software, even if advised of the possibility of such damage. |
39 | // |
40 | //M*/ |
41 | |
42 | #include "precomp.hpp" |
43 | #include "cap_interface.hpp" |
44 | |
45 | #ifdef HAVE_DC1394_2 |
46 | |
47 | #include <unistd.h> |
48 | #include <stdint.h> |
49 | #ifdef _WIN32 |
50 | // On Windows, we have no sys/select.h, but we need to pick up |
51 | // select() which is in winsock2. |
52 | #ifndef __SYS_SELECT_H__ |
53 | #define __SYS_SELECT_H__ 1 |
54 | #include <winsock2.h> |
55 | #endif |
56 | #else |
57 | #include <sys/select.h> |
58 | #endif /*_WIN32*/ |
59 | #include <dc1394/dc1394.h> |
60 | #include <stdlib.h> |
61 | #include <string.h> |
62 | |
63 | struct CvDC1394 |
64 | { |
65 | CvDC1394(); |
66 | ~CvDC1394(); |
67 | |
68 | dc1394_t* dc; |
69 | fd_set camFds; |
70 | }; |
71 | |
72 | CvDC1394::CvDC1394() |
73 | { |
74 | dc = dc1394_new(); |
75 | FD_ZERO(&camFds); |
76 | } |
77 | |
78 | CvDC1394::~CvDC1394() |
79 | { |
80 | if (dc) |
81 | dc1394_free(dc1394: dc); |
82 | dc = 0; |
83 | } |
84 | |
85 | static CvDC1394& getDC1394() |
86 | { |
87 | static CvDC1394 dc1394; |
88 | return dc1394; |
89 | } |
90 | |
91 | class CvCaptureCAM_DC1394_v2_CPP : public CvCapture |
92 | { |
93 | public: |
94 | static int dc1394properties[CV_CAP_PROP_MAX_DC1394]; |
95 | CvCaptureCAM_DC1394_v2_CPP(); |
96 | virtual ~CvCaptureCAM_DC1394_v2_CPP() |
97 | { |
98 | close(); |
99 | } |
100 | |
101 | virtual bool open(int index); |
102 | virtual void close(); |
103 | |
104 | virtual double getProperty(int) const CV_OVERRIDE; |
105 | virtual bool setProperty(int, double) CV_OVERRIDE; |
106 | virtual bool grabFrame() CV_OVERRIDE; |
107 | virtual IplImage* retrieveFrame(int) CV_OVERRIDE; |
108 | virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_DC1394; } |
109 | |
110 | |
111 | protected: |
112 | virtual bool startCapture(); |
113 | |
114 | uint64_t guid; |
115 | dc1394camera_t* dcCam; |
116 | int isoSpeed; |
117 | int videoMode; |
118 | int frameWidth, frameHeight; |
119 | double fps; |
120 | int nDMABufs; |
121 | bool started; |
122 | int userMode; |
123 | |
124 | enum { VIDERE = 0x5505 }; |
125 | |
126 | int cameraId; |
127 | bool colorStereo; |
128 | dc1394bayer_method_t bayer; |
129 | dc1394color_filter_t bayerFilter; |
130 | |
131 | enum { NIMG = 2 }; |
132 | IplImage *img[NIMG]; |
133 | dc1394video_frame_t* frameC; |
134 | int nimages; |
135 | |
136 | dc1394featureset_t feature_set; |
137 | }; |
138 | //mapping CV_CAP_PROP_ to DC1394_FEATUREs |
139 | int CvCaptureCAM_DC1394_v2_CPP::dc1394properties[CV_CAP_PROP_MAX_DC1394] = { |
140 | -1, //no corresponding feature for CV_CAP_PROP_POS_MSEC |
141 | -1,-1,-1,-1, |
142 | DC1394_FEATURE_FRAME_RATE, //CV_CAP_PROP_FPS - fps can be set for format 7 only! |
143 | -1,-1,-1,-1, |
144 | DC1394_FEATURE_BRIGHTNESS, //CV_CAP_PROP_BRIGHTNESS 10 |
145 | -1, |
146 | DC1394_FEATURE_SATURATION, //CV_CAP_PROP_SATURATION |
147 | DC1394_FEATURE_HUE, |
148 | DC1394_FEATURE_GAIN, |
149 | DC1394_FEATURE_SHUTTER, //CV_CAP_PROP_EXPOSURE |
150 | -1, //CV_CAP_PROP_CONVERT_RGB |
151 | DC1394_FEATURE_WHITE_BALANCE, //corresponds to CV_CAP_PROP_WHITE_BALANCE_BLUE_U and CV_CAP_PROP_WHITE_BALANCE_RED_V, see set function to check these props are set |
152 | -1,-1, |
153 | DC1394_FEATURE_SHARPNESS, //20 |
154 | DC1394_FEATURE_EXPOSURE, //CV_CAP_PROP_AUTO_EXPOSURE - this is auto exposure according to the IIDC standard |
155 | DC1394_FEATURE_GAMMA, //CV_CAP_PROP_GAMMA |
156 | DC1394_FEATURE_TEMPERATURE, //CV_CAP_PROP_TEMPERATURE |
157 | DC1394_FEATURE_TRIGGER, //CV_CAP_PROP_TRIGGER |
158 | DC1394_FEATURE_TRIGGER_DELAY, //CV_CAP_PROP_TRIGGER_DELAY |
159 | DC1394_FEATURE_WHITE_BALANCE, //CV_CAP_PROP_WHITE_BALANCE_RED_V |
160 | DC1394_FEATURE_ZOOM, //CV_CAP_PROP_ZOOM |
161 | DC1394_FEATURE_FOCUS, //CV_CAP_PROP_FOCUS |
162 | -1 //CV_CAP_PROP_GUID |
163 | }; |
164 | CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP() |
165 | { |
166 | guid = 0; |
167 | dcCam = 0; |
168 | isoSpeed = 400; |
169 | fps = 15; |
170 | // Reset the value here to 1 in order to ensure only a single frame is stored in the buffer! |
171 | nDMABufs = 8; |
172 | started = false; |
173 | cameraId = 0; |
174 | colorStereo = false; |
175 | bayer = DC1394_BAYER_METHOD_BILINEAR; |
176 | bayerFilter = DC1394_COLOR_FILTER_GRBG; |
177 | frameWidth = 640; |
178 | frameHeight = 480; |
179 | |
180 | for (int i = 0; i < NIMG; i++) |
181 | img[i] = 0; |
182 | frameC = 0; |
183 | nimages = 1; |
184 | userMode = -1; |
185 | } |
186 | |
187 | |
188 | bool CvCaptureCAM_DC1394_v2_CPP::startCapture() |
189 | { |
190 | int i; |
191 | int code = 0; |
192 | if (!dcCam) |
193 | return false; |
194 | if (isoSpeed > 0) |
195 | { |
196 | // if capable set operation mode to 1394b for iso speeds above 400 |
197 | if (isoSpeed > 400 && dcCam->bmode_capable == DC1394_TRUE) |
198 | { |
199 | dc1394_video_set_operation_mode(camera: dcCam, mode: DC1394_OPERATION_MODE_1394B); |
200 | } |
201 | code = dc1394_video_set_iso_speed(camera: dcCam, |
202 | speed: isoSpeed <= 100 ? DC1394_ISO_SPEED_100 : |
203 | isoSpeed <= 200 ? DC1394_ISO_SPEED_200 : |
204 | isoSpeed <= 400 ? DC1394_ISO_SPEED_400 : |
205 | isoSpeed <= 800 ? DC1394_ISO_SPEED_800 : |
206 | isoSpeed == 1600 ? DC1394_ISO_SPEED_1600 : |
207 | DC1394_ISO_SPEED_3200); |
208 | } |
209 | |
210 | dc1394video_modes_t videoModes; |
211 | dc1394_video_get_supported_modes(camera: dcCam, video_modes: &videoModes); |
212 | |
213 | // should a specific mode be used |
214 | while (userMode >= 0) // 'if' semantic, no real loop here |
215 | { |
216 | dc1394video_mode_t wantedMode; |
217 | |
218 | if (userMode < (int)videoModes.num) |
219 | { |
220 | // set mode from number, for example the second supported mode, i.e userMode = 1 |
221 | wantedMode = videoModes.modes[userMode]; |
222 | } |
223 | else if ((userMode >= DC1394_VIDEO_MODE_MIN) && (userMode <= DC1394_VIDEO_MODE_MAX)) |
224 | { |
225 | // set modes directly from DC134 constants (from dc1394video_mode_t) |
226 | |
227 | //search for wanted mode, to check if camera supports it |
228 | int j = 0; |
229 | while ((j < (int)videoModes.num) && videoModes.modes[j] != userMode) |
230 | { |
231 | j++; |
232 | } |
233 | if (!(j < (int)videoModes.num)) |
234 | { |
235 | userMode = -1; // wanted mode not supported, search for best mode |
236 | break; |
237 | } |
238 | |
239 | wantedMode = videoModes.modes[j]; |
240 | } |
241 | else |
242 | { |
243 | userMode = -1; // wanted mode not supported, search for best mode |
244 | break; |
245 | } |
246 | |
247 | //if userMode is available: set it and update size |
248 | { |
249 | code = dc1394_video_set_mode(camera: dcCam, video_mode: wantedMode); |
250 | uint32_t width = 0, height = 0; |
251 | dc1394_get_image_size_from_video_mode(camera: dcCam, video_mode: wantedMode, width: &width, height: &height); |
252 | frameWidth = (int)width; |
253 | frameHeight = (int)height; |
254 | } |
255 | break; |
256 | } |
257 | |
258 | if (userMode == -1 && (frameWidth > 0 || frameHeight > 0)) |
259 | { |
260 | dc1394video_mode_t bestMode = (dc1394video_mode_t)(-1); |
261 | for (i = 0; i < (int)videoModes.num; i++) |
262 | { |
263 | dc1394video_mode_t mode = videoModes.modes[i]; |
264 | if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX) |
265 | continue; |
266 | int pref = -1; |
267 | dc1394color_coding_t colorCoding; |
268 | dc1394_get_color_coding_from_video_mode(camera: dcCam, video_mode: mode, color_coding: &colorCoding); |
269 | |
270 | uint32_t width, height; |
271 | dc1394_get_image_size_from_video_mode(camera: dcCam, video_mode: mode, width: &width, height: &height); |
272 | if ((int)width == frameWidth || (int)height == frameHeight) |
273 | { |
274 | if (colorCoding == DC1394_COLOR_CODING_RGB8 || |
275 | colorCoding == DC1394_COLOR_CODING_RAW8) |
276 | { |
277 | bestMode = mode; |
278 | break; |
279 | } |
280 | |
281 | if (colorCoding == DC1394_COLOR_CODING_YUV411 || |
282 | colorCoding == DC1394_COLOR_CODING_YUV422 || |
283 | (colorCoding == DC1394_COLOR_CODING_YUV444 && |
284 | pref < 1)) |
285 | { |
286 | bestMode = mode; |
287 | pref = 1; |
288 | break; |
289 | } |
290 | |
291 | if (colorCoding == DC1394_COLOR_CODING_MONO8) |
292 | { |
293 | bestMode = mode; |
294 | pref = 0; |
295 | } |
296 | } |
297 | } |
298 | if ((int)bestMode >= 0) |
299 | code = dc1394_video_set_mode(camera: dcCam, video_mode: bestMode); |
300 | } |
301 | |
302 | if (fps > 0) |
303 | { |
304 | dc1394video_mode_t mode; |
305 | dc1394framerates_t framerates; |
306 | double minDiff = DBL_MAX; |
307 | dc1394framerate_t bestFps = (dc1394framerate_t) - 1; |
308 | |
309 | dc1394_video_get_mode(camera: dcCam, video_mode: &mode); |
310 | dc1394_video_get_supported_framerates(camera: dcCam, video_mode: mode, framerates: &framerates); |
311 | |
312 | for (i = 0; i < (int)framerates.num; i++) |
313 | { |
314 | dc1394framerate_t ifps = framerates.framerates[i]; |
315 | double fps1 = (1 << (ifps - DC1394_FRAMERATE_1_875)) * 1.875; |
316 | double diff = fabs(x: fps1 - fps); |
317 | if (diff < minDiff) |
318 | { |
319 | minDiff = diff; |
320 | bestFps = ifps; |
321 | } |
322 | } |
323 | if ((int)bestFps >= 0) |
324 | code = dc1394_video_set_framerate(camera: dcCam, framerate: bestFps); |
325 | } |
326 | |
327 | if (cameraId == VIDERE) |
328 | { |
329 | bayerFilter = DC1394_COLOR_FILTER_GBRG; |
330 | nimages = 2; |
331 | uint32_t value = 0; |
332 | dc1394_get_control_register(camera: dcCam, offset: 0x50c, value: &value); |
333 | colorStereo = (value & 0x80000000) != 0; |
334 | } |
335 | |
336 | code = dc1394_capture_setup(camera: dcCam, num_dma_buffers: nDMABufs, DC1394_CAPTURE_FLAGS_DEFAULT); |
337 | if (code >= 0) |
338 | { |
339 | FD_SET(dc1394_capture_get_fileno(dcCam), &getDC1394().camFds); |
340 | dc1394_video_set_transmission(camera: dcCam, pwr: DC1394_ON); |
341 | started = true; |
342 | } |
343 | |
344 | return code >= 0; |
345 | } |
346 | |
347 | bool CvCaptureCAM_DC1394_v2_CPP::open(int index) |
348 | { |
349 | bool result = false; |
350 | dc1394camera_list_t* cameraList = 0; |
351 | dc1394error_t err; |
352 | |
353 | close(); |
354 | |
355 | if (!getDC1394().dc) |
356 | goto _exit_; |
357 | |
358 | err = dc1394_camera_enumerate(dc1394: getDC1394().dc, list: &cameraList); |
359 | if (err < 0 || !cameraList || (unsigned)index >= (unsigned)cameraList->num) |
360 | goto _exit_; |
361 | |
362 | guid = cameraList->ids[index].guid; |
363 | dcCam = dc1394_camera_new(dc1394: getDC1394().dc, guid); |
364 | if (!dcCam) |
365 | goto _exit_; |
366 | |
367 | cameraId = dcCam->vendor_id; |
368 | //get all features |
369 | if (dc1394_feature_get_all(camera: dcCam,features: &feature_set) == DC1394_SUCCESS) |
370 | result = true; |
371 | else |
372 | result = false; |
373 | |
374 | _exit_: |
375 | if (cameraList) |
376 | dc1394_camera_free_list(list: cameraList); |
377 | |
378 | return result; |
379 | } |
380 | |
381 | void CvCaptureCAM_DC1394_v2_CPP::close() |
382 | { |
383 | if (dcCam) |
384 | { |
385 | // check for fileno valid before using |
386 | int fileno=dc1394_capture_get_fileno(camera: dcCam); |
387 | |
388 | if (fileno>=0 && FD_ISSET(fileno, &getDC1394().camFds)) |
389 | FD_CLR(fileno, &getDC1394().camFds); |
390 | dc1394_video_set_transmission(camera: dcCam, pwr: DC1394_OFF); |
391 | dc1394_capture_stop(camera: dcCam); |
392 | dc1394_camera_free(camera: dcCam); |
393 | dcCam = 0; |
394 | started = false; |
395 | } |
396 | |
397 | for (int i = 0; i < NIMG; i++) |
398 | { |
399 | cvReleaseImage(image: &img[i]); |
400 | } |
401 | if (frameC) |
402 | { |
403 | if (frameC->image) |
404 | free(ptr: frameC->image); |
405 | free(ptr: frameC); |
406 | frameC = 0; |
407 | } |
408 | } |
409 | |
410 | |
411 | bool CvCaptureCAM_DC1394_v2_CPP::grabFrame() |
412 | { |
413 | dc1394capture_policy_t policy = DC1394_CAPTURE_POLICY_WAIT; |
414 | bool code = false, isColor; |
415 | dc1394video_frame_t *dcFrame = 0, *fs = 0; |
416 | int i, nch; |
417 | |
418 | if (!dcCam || (!started && !startCapture())) |
419 | return false; |
420 | |
421 | dc1394_capture_dequeue(camera: dcCam, policy, frame: &dcFrame); |
422 | |
423 | if (!dcFrame) |
424 | return false; |
425 | |
426 | if (/*dcFrame->frames_behind > 1 ||*/ dc1394_capture_is_frame_corrupt(camera: dcCam, frame: dcFrame) == DC1394_TRUE) |
427 | { |
428 | goto _exit_; |
429 | } |
430 | |
431 | isColor = dcFrame->color_coding != DC1394_COLOR_CODING_MONO8 && |
432 | dcFrame->color_coding != DC1394_COLOR_CODING_MONO16 && |
433 | dcFrame->color_coding != DC1394_COLOR_CODING_MONO16S; |
434 | |
435 | if (nimages == 2) |
436 | { |
437 | fs = (dc1394video_frame_t*)calloc(nmemb: 1, size: sizeof(*fs)); |
438 | dc1394_deinterlace_stereo_frames(in: dcFrame, out: fs, method: DC1394_STEREO_METHOD_INTERLACED); |
439 | dc1394_capture_enqueue(camera: dcCam, frame: dcFrame); // release the captured frame as soon as possible |
440 | dcFrame = 0; |
441 | if (!fs->image) |
442 | goto _exit_; |
443 | isColor = colorStereo; |
444 | } |
445 | nch = isColor ? 3 : 1; |
446 | |
447 | for (i = 0; i < nimages; i++) |
448 | { |
449 | IplImage fhdr; |
450 | dc1394video_frame_t f = fs ? *fs : *dcFrame, *fc = &f; |
451 | f.size[1] /= nimages; |
452 | f.image += f.size[0] * f.size[1] * i; // TODO: make it more universal |
453 | if (isColor) |
454 | { |
455 | if (!frameC) |
456 | frameC = (dc1394video_frame_t*)calloc(nmemb: 1, size: sizeof(*frameC)); |
457 | frameC->color_coding = nch == 3 ? DC1394_COLOR_CODING_RGB8 : DC1394_COLOR_CODING_MONO8; |
458 | if (nimages == 1) |
459 | { |
460 | dc1394_convert_frames(in: &f, out: frameC); |
461 | dc1394_capture_enqueue(camera: dcCam, frame: dcFrame); |
462 | dcFrame = 0; |
463 | } |
464 | else |
465 | { |
466 | f.color_filter = bayerFilter; |
467 | dc1394_debayer_frames(in: &f, out: frameC, method: bayer); |
468 | } |
469 | fc = frameC; |
470 | } |
471 | if (!img[i]) |
472 | img[i] = cvCreateImage(size: cvSize(width: fc->size[0], height: fc->size[1]), depth: 8, channels: nch); |
473 | cvInitImageHeader(image: &fhdr, size: cvSize(width: fc->size[0], height: fc->size[1]), depth: 8, channels: nch); |
474 | cvSetData(arr: &fhdr, data: fc->image, step: fc->size[0]*nch); |
475 | |
476 | // Swap R&B channels: |
477 | if (nch==3) |
478 | { |
479 | cv::Mat tmp = cv::cvarrToMat(arr: &fhdr); |
480 | cv::cvtColor(src: tmp, dst: tmp, code: cv::COLOR_RGB2BGR, dstCn: tmp.channels()); |
481 | } |
482 | |
483 | cvCopy(src: &fhdr, dst: img[i]); |
484 | } |
485 | |
486 | code = true; |
487 | |
488 | _exit_: |
489 | if (dcFrame) |
490 | dc1394_capture_enqueue(camera: dcCam, frame: dcFrame); |
491 | if (fs) |
492 | { |
493 | if (fs->image) |
494 | free(ptr: fs->image); |
495 | free(ptr: fs); |
496 | } |
497 | |
498 | return code; |
499 | } |
500 | |
501 | IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx) |
502 | { |
503 | return 0 <= idx && idx < nimages ? img[idx] : 0; |
504 | } |
505 | |
506 | double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId) const |
507 | { |
508 | // Simulate mutable (C++11-like) member variable |
509 | dc1394featureset_t& fs = const_cast<dc1394featureset_t&>(feature_set); |
510 | |
511 | switch (propId) |
512 | { |
513 | case CV_CAP_PROP_FRAME_WIDTH: |
514 | return frameWidth ? frameWidth : frameHeight*4 / 3; |
515 | case CV_CAP_PROP_FRAME_HEIGHT: |
516 | return frameHeight ? frameHeight : frameWidth*3 / 4; |
517 | case CV_CAP_PROP_FPS: |
518 | return fps; |
519 | case CV_CAP_PROP_RECTIFICATION: |
520 | CV_LOG_WARNING(NULL, "cap_dc1394: rectification support has been removed from videoio module" ); |
521 | return 0; |
522 | case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: |
523 | if (dc1394_feature_whitebalance_get_value(camera: dcCam, |
524 | u_b_value: &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value, |
525 | v_r_value: &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS) |
526 | return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value; |
527 | break; |
528 | case CV_CAP_PROP_WHITE_BALANCE_RED_V: |
529 | if (dc1394_feature_whitebalance_get_value(camera: dcCam, |
530 | u_b_value: &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value, |
531 | v_r_value: &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS) |
532 | return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value; |
533 | break; |
534 | case CV_CAP_PROP_GUID: |
535 | //the least 32 bits are enough to identify the camera |
536 | return (double) (guid & 0x00000000FFFFFFFF); |
537 | break; |
538 | case CV_CAP_PROP_MODE: |
539 | return (double) userMode; |
540 | break; |
541 | case CV_CAP_PROP_ISO_SPEED: |
542 | return (double) isoSpeed; |
543 | case CV_CAP_PROP_BUFFERSIZE: |
544 | return (double) nDMABufs; |
545 | default: |
546 | if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1 |
547 | && dcCam) |
548 | //&& feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable) |
549 | if (dc1394_feature_get_value(camera: dcCam,feature: (dc1394feature_t)dc1394properties[propId], |
550 | value: &fs.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value) == DC1394_SUCCESS) |
551 | return feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value; |
552 | } |
553 | return -1; // the value of the feature can be 0, so returning 0 as an error is wrong |
554 | } |
555 | |
556 | bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value) |
557 | { |
558 | switch (propId) |
559 | { |
560 | case CV_CAP_PROP_FRAME_WIDTH: |
561 | if(started) |
562 | return false; |
563 | frameWidth = cvRound(value); |
564 | frameHeight = 0; |
565 | break; |
566 | case CV_CAP_PROP_FRAME_HEIGHT: |
567 | if(started) |
568 | return false; |
569 | frameWidth = 0; |
570 | frameHeight = cvRound(value); |
571 | break; |
572 | case CV_CAP_PROP_FPS: |
573 | if(started) |
574 | return false; |
575 | fps = value; |
576 | break; |
577 | case CV_CAP_PROP_RECTIFICATION: |
578 | CV_LOG_WARNING(NULL, "cap_dc1394: rectification support has been removed from videoio module" ); |
579 | return false; |
580 | case CV_CAP_PROP_MODE: |
581 | if(started) |
582 | return false; |
583 | userMode = cvRound(value); |
584 | break; |
585 | case CV_CAP_PROP_ISO_SPEED: |
586 | if(started) |
587 | return false; |
588 | isoSpeed = cvRound(value); |
589 | break; |
590 | case CV_CAP_PROP_BUFFERSIZE: |
591 | if(started) |
592 | return false; |
593 | nDMABufs = value; |
594 | break; |
595 | //The code below is based on coriander, callbacks.c:795, refer to case RANGE_MENU_MAN : |
596 | default: |
597 | if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1 |
598 | && dcCam) |
599 | { |
600 | //get the corresponding feature from property-id |
601 | dc1394feature_info_t *act_feature = &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN]; |
602 | |
603 | if (cvRound(value) == CV_CAP_PROP_DC1394_OFF) |
604 | { |
605 | if ( (act_feature->on_off_capable) |
606 | && (dc1394_feature_set_power(camera: dcCam, feature: act_feature->id, pwr: DC1394_OFF) == DC1394_SUCCESS)) |
607 | { |
608 | act_feature->is_on=DC1394_OFF; |
609 | return true; |
610 | } |
611 | return false; |
612 | } |
613 | //try to turn the feature ON, feature can be ON and at the same time it can be not capable to change state to OFF |
614 | if ( (act_feature->is_on == DC1394_OFF) && (act_feature->on_off_capable == DC1394_TRUE)) |
615 | { |
616 | if (dc1394_feature_set_power(camera: dcCam, feature: act_feature->id, pwr: DC1394_ON) == DC1394_SUCCESS) |
617 | feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on=DC1394_ON; |
618 | } |
619 | //turn off absolute mode - the actual value will be stored in the value field, |
620 | //otherwise it would be stored into CSR (control and status register) absolute value |
621 | if (act_feature->absolute_capable |
622 | && dc1394_feature_set_absolute_control(camera: dcCam, feature: act_feature->id, pwr: DC1394_OFF) !=DC1394_SUCCESS) |
623 | return false; |
624 | else |
625 | act_feature->abs_control=DC1394_OFF; |
626 | //set AUTO |
627 | if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_AUTO) |
628 | { |
629 | if (dc1394_feature_set_mode(camera: dcCam, feature: act_feature->id, mode: DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS) |
630 | return false; |
631 | act_feature->current_mode=DC1394_FEATURE_MODE_AUTO; |
632 | return true; |
633 | } |
634 | //set ONE PUSH |
635 | if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO) |
636 | { |
637 | //have to set to manual first, otherwise one push will be ignored (AVT manual 4.3.0 p. 115) |
638 | if (dc1394_feature_set_mode(camera: dcCam, feature: act_feature->id, mode: DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS) |
639 | return false; |
640 | //will change to |
641 | act_feature->current_mode=DC1394_FEATURE_MODE_ONE_PUSH_AUTO; |
642 | return true; |
643 | } |
644 | //set the feature to MANUAL mode, |
645 | if (dc1394_feature_set_mode(camera: dcCam, feature: act_feature->id, mode: DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS) |
646 | return false; |
647 | else |
648 | act_feature->current_mode=DC1394_FEATURE_MODE_MANUAL; |
649 | // if property is one of the white balance features treat it in different way |
650 | if (propId == CV_CAP_PROP_WHITE_BALANCE_BLUE_U) |
651 | { |
652 | if (dc1394_feature_whitebalance_set_value(camera: dcCam,u_b_value: cvRound(value), v_r_value: act_feature->RV_value)!=DC1394_SUCCESS) |
653 | return false; |
654 | else |
655 | { |
656 | act_feature->BU_value = cvRound(value); |
657 | return true; |
658 | } |
659 | } |
660 | if (propId == CV_CAP_PROP_WHITE_BALANCE_RED_V) |
661 | { |
662 | if (dc1394_feature_whitebalance_set_value(camera: dcCam, u_b_value: act_feature->BU_value, v_r_value: cvRound(value))!=DC1394_SUCCESS) |
663 | return false; |
664 | else |
665 | { |
666 | act_feature->RV_value = cvRound(value); |
667 | return true; |
668 | } |
669 | } |
670 | |
671 | //first: check boundaries |
672 | if (value < act_feature->min) |
673 | { |
674 | value = act_feature->min; |
675 | } |
676 | else if (value > act_feature->max) |
677 | { |
678 | value = act_feature->max; |
679 | } |
680 | |
681 | if (dc1394_feature_set_value(camera: dcCam, feature: act_feature->id, value: cvRound(value)) == DC1394_SUCCESS) |
682 | { |
683 | act_feature->value = value; |
684 | return true; |
685 | } |
686 | } |
687 | return false; |
688 | } |
689 | return true; |
690 | } |
691 | |
692 | |
693 | cv::Ptr<cv::IVideoCapture> cv::create_DC1394_capture(int index) |
694 | { |
695 | CvCaptureCAM_DC1394_v2_CPP* capture = new CvCaptureCAM_DC1394_v2_CPP; |
696 | if (capture->open(index)) |
697 | return cv::makePtr<cv::LegacyCapture>(a1: capture); |
698 | delete capture; |
699 | return 0; |
700 | } |
701 | |
702 | #endif |
703 | |