Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * firewire.cpp - Implementation to access FW cam using libdc1394 00004 * 00005 * Generated: Tue Feb 22 13:28:08 2005 00006 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <core/exception.h> 00025 #include <core/exceptions/software.h> 00026 #include <utils/system/console_colors.h> 00027 00028 #include <cstdlib> 00029 #include <unistd.h> 00030 #include <climits> 00031 #include <cstring> 00032 00033 #include <fvcams/firewire.h> 00034 #include <fvcams/cam_exceptions.h> 00035 #include <fvutils/system/camargp.h> 00036 00037 #include <dc1394/utils.h> 00038 00039 using namespace std; 00040 using namespace fawkes; 00041 00042 namespace firevision { 00043 #if 0 /* just to make Emacs auto-indent happy */ 00044 } 00045 #endif 00046 00047 /** @class FirewireCamera <fvcams/firewire.h> 00048 * Firewire camera. 00049 * This camera implementation allows for access to IEEE1394 cameras via 00050 * libdc1394. 00051 * @author Tim Niemueller 00052 */ 00053 00054 /** Constructor. 00055 * @param framerate desired framerate 00056 * @param mode desired mode 00057 * @param speed IEEE 1394 speed 00058 * @param num_buffers number of DMA buffers 00059 */ 00060 FirewireCamera::FirewireCamera(dc1394framerate_t framerate, 00061 dc1394video_mode_t mode, 00062 dc1394speed_t speed, 00063 int num_buffers) 00064 { 00065 _started = _opened = false; 00066 _valid_frame_received = false; 00067 _auto_focus = true; // assume auto_focus, checked in open() 00068 _auto_shutter = false; 00069 _auto_white_balance = false; 00070 _speed = speed; 00071 _num_buffers = num_buffers; 00072 _mode = mode; 00073 _framerate = framerate; 00074 _white_balance_ub = 0xFFFFFFFF; 00075 _white_balance_vr = 0xFFFFFFFF; 00076 _format7_mode_enabled = false; 00077 _format7_width = _format7_height = _format7_startx = _format7_starty = 0; 00078 _format7_bpp = 4096; 00079 _model = strdup("any"); 00080 _do_set_shutter = false; 00081 _do_set_white_balance = false; 00082 _do_set_focus = false; 00083 _gain = 0; 00084 _auto_gain = true; 00085 00086 _dc1394 = NULL; 00087 _camera = NULL; 00088 00089 if ((mode == DC1394_VIDEO_MODE_640x480_YUV422) && (framerate == DC1394_FRAMERATE_30)) { 00090 // cerr << "When in mode YUV422 @ 640x480 with more than 15 fps. Setting framerate to 15fps." << endl; 00091 _framerate = DC1394_FRAMERATE_15; 00092 } 00093 } 00094 00095 00096 /** Empty destructor. */ 00097 FirewireCamera::~FirewireCamera() 00098 { 00099 close(); 00100 00101 if ( _model != NULL ) { 00102 free(_model); 00103 } 00104 } 00105 00106 00107 void 00108 FirewireCamera::open() 00109 { 00110 if (_opened) return; 00111 00112 _dc1394 = dc1394_new(); 00113 dc1394camera_list_t *list; 00114 dc1394error_t err; 00115 00116 if ( dc1394_camera_enumerate(_dc1394, &list) != DC1394_SUCCESS ) { 00117 throw Exception("Could not enumerate cameras"); 00118 } 00119 00120 if (list->num > 0) { 00121 if ( strcmp(_model, "any") == 0 ) { 00122 /* use the first camera found */ 00123 _camera = dc1394_camera_new(_dc1394, list->ids[0].guid); 00124 if (! _camera) { 00125 dc1394_free(_dc1394); 00126 _dc1394 = NULL; 00127 throw Exception("Could not create camera for first foiund camera"); 00128 } 00129 } else { 00130 _camera = NULL; 00131 for (unsigned int i = 0; i < list->num; ++i) { 00132 dc1394camera_t *tmpcam = dc1394_camera_new(_dc1394, list->ids[i].guid); 00133 if ( strcmp(_model, tmpcam->model) == 0) { 00134 // found desired camera 00135 _camera = tmpcam; 00136 break; 00137 } else { 00138 dc1394_camera_free(tmpcam); 00139 } 00140 } 00141 if ( _camera == NULL ) { 00142 throw Exception("Could not find camera with model %s", _model); 00143 } 00144 } 00145 00146 if ( iso_mode_enabled() ) { 00147 dc1394_video_set_transmission(_camera, DC1394_OFF); 00148 } 00149 // These methods would cleanup the mess left behind by other processes, 00150 // but as of now (libdc1394 2.0.0 rc9) this is not supported for the Juju stack 00151 dc1394_iso_release_bandwidth(_camera, INT_MAX); 00152 for (int channel = 0; channel < 64; ++channel) { 00153 dc1394_iso_release_channel(_camera, channel); 00154 } 00155 // This is rude, but for now needed (Juju)... 00156 //dc1394_reset_bus(_camera); 00157 00158 if (_camera->bmode_capable > 0) { 00159 dc1394_video_set_operation_mode(_camera, DC1394_OPERATION_MODE_1394B); 00160 } 00161 if ( //((err = dc1394_cleanup_iso_channels_and_bandwidth(_camera)) != DC1394_SUCCESS) || 00162 ((err = dc1394_video_set_iso_speed(_camera, _speed)) != DC1394_SUCCESS) || 00163 ((err = dc1394_video_set_mode(_camera, _mode)) != DC1394_SUCCESS) || 00164 ((err = dc1394_video_set_framerate(_camera, _framerate)) != DC1394_SUCCESS) ) { 00165 throw Exception("Setting up the camera failed: %s", dc1394_error_get_string(err)); 00166 } 00167 00168 if (_format7_mode_enabled) { 00169 if (_format7_bpp == 0) { 00170 uint32_t rps; 00171 dc1394_format7_get_recommended_packet_size(_camera, _mode, &rps); 00172 _format7_bpp = rps; 00173 } 00174 00175 if ( ((err = dc1394_format7_set_image_size(_camera, _mode, _format7_width, _format7_height)) != DC1394_SUCCESS) || 00176 ((err = dc1394_format7_set_image_position(_camera, _mode, _format7_startx, _format7_starty)) != DC1394_SUCCESS) || 00177 ((err = dc1394_format7_set_color_coding(_camera, _mode, _format7_coding)) != DC1394_SUCCESS) || 00178 ((err = dc1394_format7_set_packet_size(_camera, _mode, _format7_bpp)) != DC1394_SUCCESS) ) { 00179 throw Exception("Could not setup Format7 parameters: %s", dc1394_error_get_string(err)); 00180 } 00181 } 00182 00183 set_auto_shutter(_auto_shutter); 00184 if ( !_auto_shutter && _do_set_shutter ) { 00185 set_shutter(_shutter); 00186 } 00187 00188 set_auto_focus(_auto_focus); 00189 if ( ! _auto_focus && _do_set_focus ) { 00190 set_focus(_focus); 00191 } 00192 00193 set_auto_white_balance(_auto_white_balance); 00194 if ( ! _auto_white_balance && 00195 (_white_balance_ub != 0xFFFFFFFF) && 00196 (_white_balance_vr != 0xFFFFFFFF) && 00197 _do_set_white_balance ) { 00198 set_white_balance(_white_balance_ub, _white_balance_vr); 00199 } 00200 00201 if ( !_auto_gain ) { 00202 set_gain(_gain); 00203 } 00204 00205 } else { 00206 throw Exception("No cameras connected"); 00207 } 00208 00209 _opened = true; 00210 } 00211 00212 00213 void 00214 FirewireCamera::start() 00215 { 00216 if (_started) return; 00217 00218 if (! _opened) { 00219 throw Exception("FirewireCamera: Cannot start closed camera"); 00220 } 00221 00222 dc1394error_t err; 00223 if ( (err = dc1394_capture_setup(_camera, _num_buffers, DC1394_CAPTURE_FLAGS_DEFAULT )) != DC1394_SUCCESS ) { 00224 dc1394_capture_stop(_camera); 00225 throw Exception("FirewireCamera: Could not setup capture (%s)", dc1394_error_get_string(err)); 00226 } 00227 00228 if ( (err = dc1394_video_set_transmission(_camera, DC1394_ON)) != DC1394_SUCCESS) { 00229 // cout << cred << "Could not start video transmission" << cnormal << endl; 00230 dc1394_capture_stop(_camera); 00231 throw Exception("FirewireCamera: Could not start ISO transmission (%s)", dc1394_error_get_string(err)); 00232 } 00233 00234 // Give it some time to be ready 00235 usleep(500000); 00236 00237 _started = true; 00238 } 00239 00240 00241 void 00242 FirewireCamera::stop() 00243 { 00244 dc1394_video_set_transmission(_camera, DC1394_OFF); 00245 dc1394_capture_stop(_camera); 00246 _started = false; 00247 } 00248 00249 00250 /** Check if ISO mode is enabled. 00251 * @return true if isochronous transfer is running, false otherwise. 00252 * @exception Exception thrown if the transmission status could not be determined 00253 */ 00254 bool 00255 FirewireCamera::iso_mode_enabled() 00256 { 00257 dc1394switch_t status; 00258 if ( dc1394_video_get_transmission(_camera, &status) != DC1394_SUCCESS) { 00259 throw Exception("Could not get transmission status"); 00260 } else { 00261 return (status == DC1394_ON); 00262 } 00263 } 00264 00265 00266 void 00267 FirewireCamera::print_info() 00268 { 00269 if (_opened) { 00270 dc1394_camera_print_info( _camera, stdout ); 00271 } 00272 00273 printf("Parameters:\n" 00274 "valid frame received: %i\n" 00275 "auto focus: %i\n" 00276 "auto shutter: %i (shutter value: %u)\n" 00277 "auto white balance: %i (white balance value %u/%u)\n" 00278 "do set shutter: %i do set white balance: %i\n", 00279 _valid_frame_received,_auto_focus, 00280 _auto_shutter, _shutter, 00281 _auto_white_balance, _white_balance_ub, _white_balance_vr, 00282 _do_set_shutter = false, _do_set_white_balance = false 00283 ); 00284 } 00285 00286 00287 /** Get Firewire GUID of camera. 00288 * @return IEEE1394 GUID 00289 */ 00290 uint64_t 00291 FirewireCamera::guid() const 00292 { 00293 if ( ! _opened ) { 00294 throw Exception("Camera not opened"); 00295 } 00296 00297 return _camera->guid; 00298 } 00299 00300 00301 /** Get camera model. 00302 * @return string with the camera model name 00303 */ 00304 const char * 00305 FirewireCamera::model() const 00306 { 00307 if ( ! _opened ) { 00308 throw Exception("Camera not opened"); 00309 } 00310 00311 return _camera->model; 00312 } 00313 00314 00315 void 00316 FirewireCamera::capture() 00317 { 00318 00319 if (! _opened) { 00320 throw CaptureException("FirewireCamera(%s): cannot capture on closed camera", _model); 00321 } 00322 if (! _started) { 00323 throw CaptureException("FirewireCamera(%s): cannot capture on stopped camera", _model); 00324 } 00325 00326 if (! iso_mode_enabled()) { 00327 throw CaptureException("FirewireCamera(%s): isochronous transfer not active", _model); 00328 } 00329 00330 dc1394error_t err; 00331 if (DC1394_SUCCESS != (err = dc1394_capture_dequeue(_camera, DC1394_CAPTURE_POLICY_WAIT, &_frame))) { 00332 _valid_frame_received = false; 00333 throw CaptureException("FireWireCamera(%s): capture failed (%s)", 00334 _model, dc1394_error_get_string(err)); 00335 } else { 00336 _valid_frame_received = (_frame != NULL); 00337 } 00338 } 00339 00340 00341 void 00342 FirewireCamera::flush() 00343 { 00344 capture(); 00345 // HACK, needed or we will get kernel NULL pointer exception *urgh* 00346 usleep(100000); 00347 dispose_buffer(); 00348 } 00349 00350 00351 unsigned char* 00352 FirewireCamera::buffer() 00353 { 00354 if ( _valid_frame_received ) { 00355 return _frame->image; 00356 } else { 00357 return NULL; 00358 } 00359 } 00360 00361 00362 unsigned int 00363 FirewireCamera::buffer_size() 00364 { 00365 if ( _valid_frame_received ) { 00366 return _frame->total_bytes; 00367 } else { 00368 return 0; 00369 } 00370 } 00371 00372 void 00373 FirewireCamera::close() 00374 { 00375 if ( _started ) stop(); 00376 if ( _opened ) { 00377 dc1394_camera_free( _camera ); 00378 dc1394_free(_dc1394); 00379 _camera = NULL; 00380 _dc1394 = NULL; 00381 _opened = false; 00382 } 00383 } 00384 00385 00386 void 00387 FirewireCamera::dispose_buffer() 00388 { 00389 if ( _valid_frame_received ) { 00390 dc1394_capture_enqueue( _camera, _frame ); 00391 } 00392 } 00393 00394 00395 unsigned int 00396 FirewireCamera::pixel_width() 00397 { 00398 if (_opened) { 00399 if ( _valid_frame_received ) { 00400 return _frame->size[0]; 00401 } else { 00402 unsigned int width, height; 00403 dc1394error_t err; 00404 if ((err = dc1394_get_image_size_from_video_mode(_camera, _mode, &width, &height)) != DC1394_SUCCESS) { 00405 throw Exception("FirewireCamera(%s): cannot get width (%s)", _model, 00406 dc1394_error_get_string(err)); 00407 } 00408 return width; 00409 } 00410 } else { 00411 throw Exception("Camera not opened"); 00412 } 00413 } 00414 00415 00416 unsigned int 00417 FirewireCamera::pixel_height() 00418 { 00419 if (_opened) { 00420 if ( _valid_frame_received ) { 00421 return _frame->size[1]; 00422 } else { 00423 unsigned int width, height; 00424 dc1394error_t err; 00425 if ((err = dc1394_get_image_size_from_video_mode(_camera, _mode, &width, &height)) != DC1394_SUCCESS) { 00426 throw Exception("FirewireCamera(%s): cannot get width (%s)", _model, 00427 dc1394_error_get_string(err)); 00428 } 00429 return height; 00430 } 00431 } else { 00432 throw Exception("Camera not opened"); 00433 } 00434 } 00435 00436 00437 colorspace_t 00438 FirewireCamera::colorspace() 00439 { 00440 // this needs to be changed for different modes 00441 switch (_mode) { 00442 case DC1394_VIDEO_MODE_320x240_YUV422: 00443 case DC1394_VIDEO_MODE_640x480_YUV422: 00444 case DC1394_VIDEO_MODE_800x600_YUV422: 00445 case DC1394_VIDEO_MODE_1024x768_YUV422: 00446 case DC1394_VIDEO_MODE_1280x960_YUV422: 00447 case DC1394_VIDEO_MODE_1600x1200_YUV422: 00448 return YUV422_PACKED; 00449 00450 case DC1394_VIDEO_MODE_640x480_YUV411: 00451 return YUV411_PACKED; 00452 00453 00454 case DC1394_VIDEO_MODE_640x480_RGB8: 00455 case DC1394_VIDEO_MODE_800x600_RGB8: 00456 case DC1394_VIDEO_MODE_1024x768_RGB8: 00457 case DC1394_VIDEO_MODE_1280x960_RGB8: 00458 case DC1394_VIDEO_MODE_1600x1200_RGB8: 00459 return RGB; 00460 00461 case DC1394_VIDEO_MODE_640x480_MONO8: 00462 case DC1394_VIDEO_MODE_800x600_MONO8: 00463 case DC1394_VIDEO_MODE_1024x768_MONO8: 00464 case DC1394_VIDEO_MODE_1280x960_MONO8: 00465 case DC1394_VIDEO_MODE_1600x1200_MONO8: 00466 return MONO8; 00467 00468 case DC1394_VIDEO_MODE_640x480_MONO16: 00469 case DC1394_VIDEO_MODE_800x600_MONO16: 00470 case DC1394_VIDEO_MODE_1024x768_MONO16: 00471 case DC1394_VIDEO_MODE_1280x960_MONO16: 00472 case DC1394_VIDEO_MODE_1600x1200_MONO16: 00473 return MONO16; 00474 00475 case DC1394_VIDEO_MODE_FORMAT7_0: 00476 case DC1394_VIDEO_MODE_FORMAT7_1: 00477 case DC1394_VIDEO_MODE_FORMAT7_2: 00478 case DC1394_VIDEO_MODE_FORMAT7_3: 00479 case DC1394_VIDEO_MODE_FORMAT7_4: 00480 case DC1394_VIDEO_MODE_FORMAT7_5: 00481 case DC1394_VIDEO_MODE_FORMAT7_6: 00482 case DC1394_VIDEO_MODE_FORMAT7_7: 00483 switch (_format7_coding) { 00484 case DC1394_COLOR_CODING_MONO8: 00485 return MONO8; 00486 case DC1394_COLOR_CODING_YUV411: 00487 return YUV411_PACKED; 00488 case DC1394_COLOR_CODING_YUV422: 00489 return YUV422_PACKED; 00490 case DC1394_COLOR_CODING_RGB8: 00491 return RGB; 00492 case DC1394_COLOR_CODING_MONO16: 00493 return MONO16; 00494 case DC1394_COLOR_CODING_RAW8: 00495 return RAW8; 00496 case DC1394_COLOR_CODING_RAW16: 00497 return RAW16; 00498 default: 00499 return CS_UNKNOWN; 00500 } 00501 break; 00502 00503 default: 00504 return CS_UNKNOWN; 00505 } 00506 } 00507 00508 00509 bool 00510 FirewireCamera::ready() 00511 { 00512 return _started; 00513 } 00514 00515 00516 void 00517 FirewireCamera::set_image_number(unsigned int n) 00518 { 00519 } 00520 00521 00522 /* CAMERA CONTROL STUFF */ 00523 00524 void 00525 FirewireCamera::set_auto_focus(bool enabled) 00526 { 00527 dc1394error_t err; 00528 if ((err = dc1394_feature_set_mode(_camera, DC1394_FEATURE_FOCUS, 00529 enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL)) 00530 == DC1394_SUCCESS) { 00531 _auto_focus = enabled; 00532 } else { 00533 throw Exception("FirewireCamera(%s): Setting auto focus failed (%s)", _model, 00534 dc1394_error_get_string(err)); 00535 } 00536 } 00537 00538 00539 bool 00540 FirewireCamera::auto_focus() 00541 { 00542 return _auto_focus; 00543 } 00544 00545 00546 unsigned int 00547 FirewireCamera::focus() 00548 { 00549 unsigned int focus = 0; 00550 if (dc1394_feature_get_value(_camera, DC1394_FEATURE_FOCUS, &focus) == DC1394_SUCCESS) { 00551 return focus; 00552 } else { 00553 return 0; 00554 } 00555 00556 } 00557 00558 00559 void 00560 FirewireCamera::set_focus(unsigned int focus) 00561 { 00562 dc1394_feature_set_value(_camera, DC1394_FEATURE_FOCUS, focus); 00563 } 00564 00565 00566 unsigned int 00567 FirewireCamera::focus_min() 00568 { 00569 unsigned int min = 0; 00570 unsigned int max = 0; 00571 if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_FOCUS, &min, &max) == DC1394_SUCCESS) { 00572 return min; 00573 } else { 00574 return 0; 00575 } 00576 } 00577 00578 00579 unsigned int 00580 FirewireCamera::focus_max() 00581 { 00582 unsigned int max = 0; 00583 unsigned int min = 0; 00584 if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_FOCUS, &min, &max) == DC1394_SUCCESS) { 00585 return max; 00586 } else { 00587 return 0; 00588 } 00589 } 00590 00591 00592 /** Set status of auto shutter. 00593 * @param enabled true to enable auto shutter, false to disable. 00594 */ 00595 void 00596 FirewireCamera::set_auto_shutter(bool enabled) 00597 { 00598 if (dc1394_feature_set_mode(_camera, DC1394_FEATURE_SHUTTER, 00599 enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL) 00600 == DC1394_SUCCESS) { 00601 _auto_shutter = enabled; 00602 } 00603 } 00604 00605 00606 /** Get status of auto shutter. 00607 * @return true if auto shutter is enabled, false otherwise 00608 */ 00609 bool 00610 FirewireCamera::auto_shutter() 00611 { 00612 return _auto_shutter; 00613 } 00614 00615 00616 /** Set shutter value. 00617 * @param shutter shutter value 00618 */ 00619 void 00620 FirewireCamera::set_shutter(unsigned int shutter) 00621 { 00622 if ( dc1394_feature_set_value(_camera, DC1394_FEATURE_SHUTTER, shutter) != DC1394_SUCCESS ) { 00623 throw Exception("Failed to set shutter to %d", shutter); 00624 } 00625 } 00626 00627 00628 /** Get shutter value. 00629 * @return the current shutter value 00630 */ 00631 unsigned int 00632 FirewireCamera::shutter() 00633 { 00634 if ( dc1394_feature_get_value(_camera, DC1394_FEATURE_SHUTTER, &_shutter) != DC1394_SUCCESS ) { 00635 throw Exception("Failed to retrieve shutter value"); 00636 } 00637 00638 return _shutter; 00639 } 00640 00641 00642 /** Set status of auto white balance. 00643 * @param enabled true to enable auto white balance, false to disable. 00644 */ 00645 void 00646 FirewireCamera::set_auto_white_balance(bool enabled) 00647 { 00648 if (dc1394_feature_set_mode(_camera, DC1394_FEATURE_WHITE_BALANCE, 00649 enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL) 00650 == DC1394_SUCCESS) { 00651 _auto_white_balance = enabled; 00652 } 00653 } 00654 00655 00656 /** Get status of auto white balance. 00657 * @return true if white balance is enabled, false otherwise 00658 */ 00659 bool 00660 FirewireCamera::auto_white_balance() 00661 { 00662 return _auto_white_balance; 00663 } 00664 00665 00666 /** Get white balance values. 00667 * @param ub contains U/B value upon return 00668 * @param vr contains V/R value upon return 00669 */ 00670 void 00671 FirewireCamera::white_balance(unsigned int *ub, unsigned int *vr) 00672 { 00673 if ( dc1394_feature_whitebalance_get_value(_camera, &_white_balance_ub, &_white_balance_vr) != DC1394_SUCCESS ) { 00674 throw Exception("Failed to retrieve white balance values"); 00675 } 00676 00677 *ub = _white_balance_ub; 00678 *vr = _white_balance_vr; 00679 } 00680 00681 00682 /** Set white balance values. 00683 * @param ub U/B value 00684 * @param vr V/R value 00685 */ 00686 void 00687 FirewireCamera::set_white_balance(unsigned int ub, unsigned int vr) 00688 { 00689 if ( dc1394_feature_whitebalance_set_value(_camera, ub, vr) != DC1394_SUCCESS ) { 00690 throw Exception("Failed to set white balance to ub=%d vr=%d", ub, vr); 00691 } 00692 } 00693 00694 /** Set the gain. 00695 * @param gain the gain value 00696 */ 00697 void 00698 FirewireCamera::set_gain(unsigned int gain) 00699 { 00700 uint32_t min; 00701 uint32_t max; 00702 if ( dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_GAIN, &min, &max) != DC1394_SUCCESS ) { 00703 throw Exception("Failed to get boundaries for feature gain"); 00704 } 00705 if (gain < min) { 00706 gain = min; 00707 } 00708 if (max < gain) { 00709 gain = max; 00710 } 00711 if ( dc1394_feature_set_mode( _camera, DC1394_FEATURE_GAIN, DC1394_FEATURE_MODE_MANUAL ) != DC1394_SUCCESS ) { 00712 throw Exception("Failed to set manual mode for feature gain"); 00713 } 00714 if ( dc1394_feature_set_value( _camera, DC1394_FEATURE_GAIN, gain ) != DC1394_SUCCESS) { 00715 throw Exception("Failed to set value for feature gain"); 00716 } 00717 } 00718 00719 /** Parse focus and set value. 00720 * Parses the given string for a valid focus value and sets it. 00721 * @param focus string representation of value 00722 */ 00723 void 00724 FirewireCamera::parse_set_focus(const char *focus) 00725 { 00726 string f = focus; 00727 if ( f == "auto" ) { 00728 _auto_focus = true; 00729 } else if ( f == "manual" ) { 00730 _auto_focus = false; 00731 } else { 00732 char *endptr = NULL; 00733 long int focus = strtol(f.c_str(), &endptr, 10); 00734 if ( endptr[0] != 0 ) { 00735 throw TypeMismatchException("Focus value is invalid. String to int conversion failed"); 00736 } else if ( focus < 0 ) { 00737 throw OutOfBoundsException("'Focus value < 0", focus, 0, 0xFFFFFFFF); 00738 } 00739 _auto_focus = false; 00740 _focus = focus; 00741 _do_set_focus = true; 00742 } 00743 } 00744 00745 00746 /** Parse white balance and set value. 00747 * Parses the given string for a valid white balance value and sets it. 00748 * @param white_balance string representation of value 00749 */ 00750 void 00751 FirewireCamera::parse_set_white_balance(const char *white_balance) 00752 { 00753 string w = white_balance; 00754 if ( w == "auto" ) { 00755 _auto_white_balance = true; 00756 } else { 00757 // try to parse U/V values 00758 string::size_type commapos = w.find(",", 0); 00759 if ( commapos == string::npos ) { 00760 throw Exception("Illegal white balance value, neither auto and no comma found"); 00761 } 00762 string ub = w.substr(0, commapos); 00763 string vr = w.substr(commapos + 1); 00764 char *endptr; 00765 long int ub_i = strtol(ub.c_str(), &endptr, 10); 00766 if ( endptr[0] != 0 ) { 00767 throw TypeMismatchException("White balance value for U/B is invalid. " 00768 "String to int conversion failed"); 00769 } else if ( ub_i < 0 ) { 00770 throw OutOfBoundsException("White balance value for U/B < 0", ub_i, 0, 0xFFFFFFFF); 00771 } 00772 long int vr_i = strtol(vr.c_str(), &endptr, 10); 00773 if ( endptr[0] != 0 ) { 00774 throw TypeMismatchException("White balance value for V/R is invalid. " 00775 "String to int conversion failed"); 00776 } else if ( vr_i < 0 ) { 00777 throw OutOfBoundsException("White balance value for V/R < 0", vr_i, 0, 0xFFFFFFFF); 00778 } 00779 00780 _auto_white_balance = false; 00781 _white_balance_ub = ub_i; 00782 _white_balance_vr = vr_i; 00783 _do_set_white_balance = true; 00784 } 00785 } 00786 00787 00788 /** Parse shutter and set value. 00789 * Parses the given string for a valid shutter value and sets it. 00790 * @param shutter string representation of value 00791 */ 00792 void 00793 FirewireCamera::parse_set_shutter(const char *shutter) 00794 { 00795 string s = shutter; 00796 if ( s == "auto" ) { 00797 _auto_shutter = true; 00798 } else { 00799 char *endptr; 00800 long int tmp = strtol(s.c_str(), &endptr, 10); 00801 if ( endptr[0] != '\0' ) { 00802 throw TypeMismatchException("Shutter value is invalid. " 00803 "String to int conversion failed"); 00804 } else if ( tmp < 0 ) { 00805 throw OutOfBoundsException("Shutter value < 0", tmp, 0, 0xFFFFFFFF); 00806 } 00807 _auto_shutter = false; 00808 _shutter = tmp; 00809 _do_set_shutter = true; 00810 } 00811 } 00812 00813 /** Constructor. 00814 * Initialize and take parameters from camera argument parser. The following 00815 * arguments are supported: 00816 * - mode=MODE where MODE is one of 00817 * - 640x480_YUV422 00818 * - 640x480_MONO16 00819 * - FORMAT7_0 00820 * - FORMAT7_1 00821 * - FORMAT7_2 00822 * - FORMAT7_3 00823 * - FORMAT7_4 00824 * - FORMAT7_5 00825 * - FORMAT7_6 00826 * - FORMAT7_7 00827 * - coding=CODING, color coding for Format7, CODING is one of: 00828 * - YUV422 00829 * - MONO8 00830 * - MONO16 00831 * - RAW16 00832 * - isospeed=SPEED, ISO speed, SPEED is one of: 00833 * - 400 00834 * - 800 00835 * - framerate=FPS, desired rate in frames per second, FPS is one of: 00836 * - 15 00837 * - 30 00838 * - 60 00839 * - 120 00840 * - nbufs=NBUFS, number of DMA buffers, integer, 0 < n <= 32 00841 * - width=WIDTH, width in pixels of Format7 ROI 00842 * - height=HEIGHT, height in pixels of Format7 ROI 00843 * - startx=STARTX, X start of Format7 ROI 00844 * - starty=STARTY, Y start of Format7 ROI 00845 * - packetsize=BYTES, packet size in BYTES 00846 * - white_balance=(auto|U,V), white balance value, either auto for auto white balance 00847 * or U/B and V/R values for adjustment 00848 * - shutter=auto, determine the shutter time automatically 00849 * - focus=MODE, MODE is either auto for auto focus, manual for manual focus without 00850 * actually setting (for example set from external application) or a 00851 * number for the focus. 00852 * @param cap camera argument parser 00853 */ 00854 FirewireCamera::FirewireCamera(const CameraArgumentParser *cap) 00855 { 00856 _started = _opened = false; 00857 _valid_frame_received = false; 00858 _auto_focus = true; // assume auto_focus, checked in open() 00859 _auto_shutter = false; 00860 _auto_white_balance = false; 00861 _white_balance_ub = 0xFFFFFFFF; 00862 _white_balance_vr = 0xFFFFFFFF; 00863 _do_set_shutter = false; 00864 _do_set_white_balance = false; 00865 _do_set_focus = false; 00866 00867 // Defaults 00868 _mode = DC1394_VIDEO_MODE_640x480_YUV422; 00869 _speed = DC1394_ISO_SPEED_400; 00870 _framerate = DC1394_FRAMERATE_15; 00871 _camera = NULL; 00872 _dc1394 = NULL; 00873 _format7_mode_enabled = false; 00874 _format7_width = _format7_height = _format7_startx = _format7_starty = 0; 00875 _format7_bpp = 4096; 00876 _model = strdup(cap->cam_id().c_str()); 00877 _num_buffers = 8; 00878 _shutter = 0; 00879 _auto_gain = true; 00880 _gain = 0; 00881 00882 if ( cap->has("mode") ) { 00883 string m = cap->get("mode"); 00884 if ( m == "640x480_MONO16" ) { 00885 _mode = DC1394_VIDEO_MODE_640x480_MONO16; 00886 } else if ( m == "FORMAT7_0" ) { 00887 _mode = DC1394_VIDEO_MODE_FORMAT7_0; 00888 _format7_mode_enabled = true; 00889 } else if ( m == "FORMAT7_1" ) { 00890 _mode = DC1394_VIDEO_MODE_FORMAT7_1; 00891 _format7_mode_enabled = true; 00892 } else if ( m == "FORMAT7_2" ) { 00893 _mode = DC1394_VIDEO_MODE_FORMAT7_2; 00894 _format7_mode_enabled = true; 00895 } else if ( m == "FORMAT7_3" ) { 00896 _mode = DC1394_VIDEO_MODE_FORMAT7_3; 00897 _format7_mode_enabled = true; 00898 } else if ( m == "FORMAT7_4" ) { 00899 _mode = DC1394_VIDEO_MODE_FORMAT7_4; 00900 _format7_mode_enabled = true; 00901 } else if ( m == "FORMAT7_5" ) { 00902 _mode = DC1394_VIDEO_MODE_FORMAT7_5; 00903 _format7_mode_enabled = true; 00904 } else if ( m == "FORMAT7_6" ) { 00905 _mode = DC1394_VIDEO_MODE_FORMAT7_6; 00906 _format7_mode_enabled = true; 00907 } else if ( m == "FORMAT7_7" ) { 00908 _mode = DC1394_VIDEO_MODE_FORMAT7_7; 00909 _format7_mode_enabled = true; 00910 } 00911 } 00912 if ( cap->has("coding") ) { 00913 string c = cap->get("coding"); 00914 if ( c == "YUV422" ) { 00915 _format7_coding = DC1394_COLOR_CODING_YUV422; 00916 } else if ( c == "MONO8" ) { 00917 _format7_coding = DC1394_COLOR_CODING_MONO8; 00918 } else if ( c == "MONO16" ) { 00919 _format7_coding = DC1394_COLOR_CODING_MONO16; 00920 } else if ( c == "RAW16" ) { 00921 _format7_coding = DC1394_COLOR_CODING_RAW16; 00922 } 00923 } 00924 if ( cap->has("isospeed") ) { 00925 string s = cap->get("isospeed"); 00926 if ( s == "400" ) { 00927 _speed = DC1394_ISO_SPEED_400; 00928 } else if ( s == "800" ) { 00929 _speed = DC1394_ISO_SPEED_800; 00930 } 00931 } 00932 if ( cap->has("framerate") ) { 00933 string f = cap->get("framerate"); 00934 if ( f == "1.875" ) { 00935 _framerate = DC1394_FRAMERATE_1_875; 00936 } else if ( f == "3.75" ) { 00937 _framerate = DC1394_FRAMERATE_3_75; 00938 } else if ( f == "7.5" ) { 00939 _framerate = DC1394_FRAMERATE_7_5; 00940 } else if ( f == "15" ) { 00941 _framerate = DC1394_FRAMERATE_15; 00942 } else if ( f == "30" ) { 00943 _framerate = DC1394_FRAMERATE_30; 00944 } else if ( f == "60" ) { 00945 _framerate = DC1394_FRAMERATE_60; 00946 } else if ( f == "120" ) { 00947 _framerate = DC1394_FRAMERATE_120; 00948 } else if ( f == "240" ) { 00949 _framerate = DC1394_FRAMERATE_240; 00950 } 00951 } 00952 if ( cap->has("focus") ) { 00953 parse_set_focus(cap->get("focus").c_str()); 00954 } 00955 if ( cap->has("nbufs") ) { 00956 _num_buffers = atoi(cap->get("nbufs").c_str()); 00957 } 00958 if ( cap->has("width") ) { 00959 _format7_width = atoi(cap->get("width").c_str()); 00960 } 00961 if ( cap->has("height") ) { 00962 _format7_height = atoi(cap->get("height").c_str()); 00963 } 00964 if ( cap->has("startx") ) { 00965 _format7_startx = atoi(cap->get("startx").c_str()); 00966 } 00967 if ( cap->has("starty") ) { 00968 _format7_starty = atoi(cap->get("starty").c_str()); 00969 } 00970 if ( cap->has("packetsize") ) { 00971 string p = cap->get("packetsize"); 00972 if ( p == "recommended" ) { 00973 _format7_bpp = 0; 00974 } else { 00975 _format7_bpp = atoi(p.c_str()); 00976 } 00977 } 00978 if ( cap->has("gain") ) { 00979 string g = cap->get("gain"); 00980 if ( g != "auto" ) { 00981 _gain = atoi(g.c_str()); 00982 _auto_gain = false; 00983 } 00984 } 00985 if ( cap->has("white_balance") ) { 00986 parse_set_white_balance(cap->get("white_balance").c_str()); 00987 } 00988 if ( cap->has("shutter") ) { 00989 parse_set_shutter(cap->get("shutter").c_str()); 00990 } 00991 } 00992 00993 00994 /** Print list of cameras. 00995 * Prints a list of available cameras to stdout. 00996 */ 00997 void 00998 FirewireCamera::print_available_fwcams() 00999 { 01000 01001 dc1394_t *dc1394 = dc1394_new(); 01002 dc1394camera_list_t *list; 01003 dc1394error_t err; 01004 if ( (err = dc1394_camera_enumerate(dc1394, &list)) != DC1394_SUCCESS ) { 01005 throw Exception("Could not enumerate cameras: %s", dc1394_error_get_string(err)); 01006 } 01007 01008 if (list->num > 0) { 01009 for (unsigned int i = 0; i < list->num; ++i) { 01010 dc1394camera_t *tmpcam = dc1394_camera_new(dc1394, list->ids[i].guid); 01011 dc1394_camera_print_info(tmpcam, stdout); 01012 dc1394_camera_free(tmpcam); 01013 } 01014 } else { 01015 printf("Could not find any cameras\n"); 01016 } 01017 } 01018 01019 } // end namespace firevision