Fawkes API  Fawkes Development Version
firewire.cpp
1 
2 /***************************************************************************
3  * firewire.cpp - Implementation to access FW cam using libdc1394
4  *
5  * Generated: Tue Feb 22 13:28:08 2005
6  * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <core/exception.h>
25 #include <core/exceptions/software.h>
26 #include <utils/system/console_colors.h>
27 
28 #include <cstdlib>
29 #include <unistd.h>
30 #include <climits>
31 #include <cstring>
32 
33 #include <fvcams/firewire.h>
34 #include <fvcams/cam_exceptions.h>
35 #include <fvutils/system/camargp.h>
36 
37 #include <dc1394/utils.h>
38 
39 using namespace std;
40 using namespace fawkes;
41 
42 namespace firevision {
43 #if 0 /* just to make Emacs auto-indent happy */
44 }
45 #endif
46 
47 /** @class FirewireCamera <fvcams/firewire.h>
48  * Firewire camera.
49  * This camera implementation allows for access to IEEE1394 cameras via
50  * libdc1394.
51  * @author Tim Niemueller
52  */
53 
54 /** Constructor.
55  * @param framerate desired framerate
56  * @param mode desired mode
57  * @param speed IEEE 1394 speed
58  * @param num_buffers number of DMA buffers
59  */
60 FirewireCamera::FirewireCamera(dc1394framerate_t framerate,
61  dc1394video_mode_t mode,
62  dc1394speed_t speed,
63  int num_buffers)
64 {
65  _started = _opened = false;
66  _valid_frame_received = false;
67  _auto_focus = true; // assume auto_focus, checked in open()
68  _auto_shutter = false;
69  _auto_white_balance = false;
70  _speed = speed;
71  _num_buffers = num_buffers;
72  _mode = mode;
73  _framerate = framerate;
74  _white_balance_ub = 0xFFFFFFFF;
75  _white_balance_vr = 0xFFFFFFFF;
76  _format7_mode_enabled = false;
77  _format7_width = _format7_height = _format7_startx = _format7_starty = 0;
78  _format7_bpp = 4096;
79  _model = strdup("any");
80  _do_set_shutter = false;
81  _do_set_white_balance = false;
82  _do_set_focus = false;
83  _gain = 0;
84  _auto_gain = true;
85 
86  _dc1394 = NULL;
87  _camera = NULL;
88 
89  if ((mode == DC1394_VIDEO_MODE_640x480_YUV422) && (framerate == DC1394_FRAMERATE_30)) {
90  // cerr << "When in mode YUV422 @ 640x480 with more than 15 fps. Setting framerate to 15fps." << endl;
91  _framerate = DC1394_FRAMERATE_15;
92  }
93 }
94 
95 
96 /** Empty destructor. */
97 FirewireCamera::~FirewireCamera()
98 {
99  close();
100 
101  if ( _model != NULL ) {
102  free(_model);
103  }
104 }
105 
106 
107 void
108 FirewireCamera::open()
109 {
110  if (_opened) return;
111 
112  _dc1394 = dc1394_new();
113  dc1394camera_list_t *list;
114  dc1394error_t err;
115 
116  if ( dc1394_camera_enumerate(_dc1394, &list) != DC1394_SUCCESS ) {
117  throw Exception("Could not enumerate cameras");
118  }
119 
120  if (list->num > 0) {
121  if ( strcmp(_model, "any") == 0 ) {
122  /* use the first camera found */
123  _camera = dc1394_camera_new(_dc1394, list->ids[0].guid);
124  if (! _camera) {
125  dc1394_free(_dc1394);
126  _dc1394 = NULL;
127  throw Exception("Could not create camera for first foiund camera");
128  }
129  } else {
130  _camera = NULL;
131  for (unsigned int i = 0; i < list->num; ++i) {
132  dc1394camera_t *tmpcam = dc1394_camera_new(_dc1394, list->ids[i].guid);
133  if ( strcmp(_model, tmpcam->model) == 0) {
134  // found desired camera
135  _camera = tmpcam;
136  break;
137  } else {
138  dc1394_camera_free(tmpcam);
139  }
140  }
141  if ( _camera == NULL ) {
142  throw Exception("Could not find camera with model %s", _model);
143  }
144  }
145 
146  if ( iso_mode_enabled() ) {
147  dc1394_video_set_transmission(_camera, DC1394_OFF);
148  }
149  // These methods would cleanup the mess left behind by other processes,
150  // but as of now (libdc1394 2.0.0 rc9) this is not supported for the Juju stack
151  dc1394_iso_release_bandwidth(_camera, INT_MAX);
152  for (int channel = 0; channel < 64; ++channel) {
153  dc1394_iso_release_channel(_camera, channel);
154  }
155  // This is rude, but for now needed (Juju)...
156  //dc1394_reset_bus(_camera);
157 
158  if (_camera->bmode_capable > 0) {
159  dc1394_video_set_operation_mode(_camera, DC1394_OPERATION_MODE_1394B);
160  }
161  if ( //((err = dc1394_cleanup_iso_channels_and_bandwidth(_camera)) != DC1394_SUCCESS) ||
162  ((err = dc1394_video_set_iso_speed(_camera, _speed)) != DC1394_SUCCESS) ||
163  ((err = dc1394_video_set_mode(_camera, _mode)) != DC1394_SUCCESS) ||
164  ((err = dc1394_video_set_framerate(_camera, _framerate)) != DC1394_SUCCESS) ) {
165  throw Exception("Setting up the camera failed: %s", dc1394_error_get_string(err));
166  }
167 
168  if (_format7_mode_enabled) {
169  if (_format7_bpp == 0) {
170  uint32_t rps;
171  dc1394_format7_get_recommended_packet_size(_camera, _mode, &rps);
172  _format7_bpp = rps;
173  }
174 
175  if ( ((err = dc1394_format7_set_image_size(_camera, _mode, _format7_width, _format7_height)) != DC1394_SUCCESS) ||
176  ((err = dc1394_format7_set_image_position(_camera, _mode, _format7_startx, _format7_starty)) != DC1394_SUCCESS) ||
177  ((err = dc1394_format7_set_color_coding(_camera, _mode, _format7_coding)) != DC1394_SUCCESS) ||
178  ((err = dc1394_format7_set_packet_size(_camera, _mode, _format7_bpp)) != DC1394_SUCCESS) ) {
179  throw Exception("Could not setup Format7 parameters: %s", dc1394_error_get_string(err));
180  }
181  }
182 
183  set_auto_shutter(_auto_shutter);
184  if ( !_auto_shutter && _do_set_shutter ) {
185  set_shutter(_shutter);
186  }
187 
188  set_auto_focus(_auto_focus);
189  if ( ! _auto_focus && _do_set_focus ) {
190  set_focus(_focus);
191  }
192 
193  set_auto_white_balance(_auto_white_balance);
194  if ( ! _auto_white_balance &&
195  (_white_balance_ub != 0xFFFFFFFF) &&
196  (_white_balance_vr != 0xFFFFFFFF) &&
197  _do_set_white_balance ) {
198  set_white_balance(_white_balance_ub, _white_balance_vr);
199  }
200 
201  if ( !_auto_gain ) {
202  set_gain(_gain);
203  }
204 
205  } else {
206  throw Exception("No cameras connected");
207  }
208 
209  _opened = true;
210 }
211 
212 
213 void
214 FirewireCamera::start()
215 {
216  if (_started) return;
217 
218  if (! _opened) {
219  throw Exception("FirewireCamera: Cannot start closed camera");
220  }
221 
222  dc1394error_t err;
223  if ( (err = dc1394_capture_setup(_camera, _num_buffers, DC1394_CAPTURE_FLAGS_DEFAULT )) != DC1394_SUCCESS ) {
224  dc1394_capture_stop(_camera);
225  throw Exception("FirewireCamera: Could not setup capture (%s)", dc1394_error_get_string(err));
226  }
227 
228  if ( (err = dc1394_video_set_transmission(_camera, DC1394_ON)) != DC1394_SUCCESS) {
229  // cout << cred << "Could not start video transmission" << cnormal << endl;
230  dc1394_capture_stop(_camera);
231  throw Exception("FirewireCamera: Could not start ISO transmission (%s)", dc1394_error_get_string(err));
232  }
233 
234  // Give it some time to be ready
235  usleep(500000);
236 
237  _started = true;
238 }
239 
240 
241 void
242 FirewireCamera::stop()
243 {
244  dc1394_video_set_transmission(_camera, DC1394_OFF);
245  dc1394_capture_stop(_camera);
246  _started = false;
247 }
248 
249 
250 /** Check if ISO mode is enabled.
251  * @return true if isochronous transfer is running, false otherwise.
252  * @exception Exception thrown if the transmission status could not be determined
253  */
254 bool
255 FirewireCamera::iso_mode_enabled()
256 {
257  dc1394switch_t status;
258  if ( dc1394_video_get_transmission(_camera, &status) != DC1394_SUCCESS) {
259  throw Exception("Could not get transmission status");
260  } else {
261  return (status == DC1394_ON);
262  }
263 }
264 
265 
266 void
267 FirewireCamera::print_info()
268 {
269  if (_opened) {
270  dc1394_camera_print_info( _camera, stdout );
271  }
272 
273  printf("Parameters:\n"
274  "valid frame received: %i\n"
275  "auto focus: %i\n"
276  "auto shutter: %i (shutter value: %u)\n"
277  "auto white balance: %i (white balance value %u/%u)\n"
278  "do set shutter: %i do set white balance: %i\n",
279  _valid_frame_received,_auto_focus,
280  _auto_shutter, _shutter,
281  _auto_white_balance, _white_balance_ub, _white_balance_vr,
282  _do_set_shutter = false, _do_set_white_balance = false
283  );
284 }
285 
286 
287 /** Get Firewire GUID of camera.
288  * @return IEEE1394 GUID
289  */
290 uint64_t
291 FirewireCamera::guid() const
292 {
293  if ( ! _opened ) {
294  throw Exception("Camera not opened");
295  }
296 
297  return _camera->guid;
298 }
299 
300 
301 /** Get camera model.
302  * @return string with the camera model name
303  */
304 const char *
305 FirewireCamera::model() const
306 {
307  if ( ! _opened ) {
308  throw Exception("Camera not opened");
309  }
310 
311  return _camera->model;
312 }
313 
314 
315 void
316 FirewireCamera::capture()
317 {
318 
319  if (! _opened) {
320  throw CaptureException("FirewireCamera(%s): cannot capture on closed camera", _model);
321  }
322  if (! _started) {
323  throw CaptureException("FirewireCamera(%s): cannot capture on stopped camera", _model);
324  }
325 
326  if (! iso_mode_enabled()) {
327  throw CaptureException("FirewireCamera(%s): isochronous transfer not active", _model);
328  }
329 
330  dc1394error_t err;
331  if (DC1394_SUCCESS != (err = dc1394_capture_dequeue(_camera, DC1394_CAPTURE_POLICY_WAIT, &_frame))) {
332  _valid_frame_received = false;
333  throw CaptureException("FireWireCamera(%s): capture failed (%s)",
334  _model, dc1394_error_get_string(err));
335  } else {
336  _valid_frame_received = (_frame != NULL);
337  }
338 }
339 
340 
341 void
342 FirewireCamera::flush()
343 {
344  capture();
345  // HACK, needed or we will get kernel NULL pointer exception *urgh*
346  usleep(100000);
347  dispose_buffer();
348 }
349 
350 
351 unsigned char*
352 FirewireCamera::buffer()
353 {
354  if ( _valid_frame_received ) {
355  return _frame->image;
356  } else {
357  return NULL;
358  }
359 }
360 
361 
362 unsigned int
363 FirewireCamera::buffer_size()
364 {
365  if ( _valid_frame_received ) {
366  return _frame->total_bytes;
367  } else {
368  return 0;
369  }
370 }
371 
372 void
373 FirewireCamera::close()
374 {
375  if ( _started ) stop();
376  if ( _opened ) {
377  dc1394_camera_free( _camera );
378  dc1394_free(_dc1394);
379  _camera = NULL;
380  _dc1394 = NULL;
381  _opened = false;
382  }
383 }
384 
385 
386 void
387 FirewireCamera::dispose_buffer()
388 {
389  if ( _valid_frame_received ) {
390  dc1394_capture_enqueue( _camera, _frame );
391  }
392 }
393 
394 
395 unsigned int
396 FirewireCamera::pixel_width()
397 {
398  if (_opened) {
399  if ( _valid_frame_received ) {
400  return _frame->size[0];
401  } else {
402  unsigned int width, height;
403  dc1394error_t err;
404  if ((err = dc1394_get_image_size_from_video_mode(_camera, _mode, &width, &height)) != DC1394_SUCCESS) {
405  throw Exception("FirewireCamera(%s): cannot get width (%s)", _model,
406  dc1394_error_get_string(err));
407  }
408  return width;
409  }
410  } else {
411  throw Exception("Camera not opened");
412  }
413 }
414 
415 
416 unsigned int
417 FirewireCamera::pixel_height()
418 {
419  if (_opened) {
420  if ( _valid_frame_received ) {
421  return _frame->size[1];
422  } else {
423  unsigned int width, height;
424  dc1394error_t err;
425  if ((err = dc1394_get_image_size_from_video_mode(_camera, _mode, &width, &height)) != DC1394_SUCCESS) {
426  throw Exception("FirewireCamera(%s): cannot get width (%s)", _model,
427  dc1394_error_get_string(err));
428  }
429  return height;
430  }
431  } else {
432  throw Exception("Camera not opened");
433  }
434 }
435 
436 
437 colorspace_t
438 FirewireCamera::colorspace()
439 {
440  // this needs to be changed for different modes
441  switch (_mode) {
442  case DC1394_VIDEO_MODE_320x240_YUV422:
443  case DC1394_VIDEO_MODE_640x480_YUV422:
444  case DC1394_VIDEO_MODE_800x600_YUV422:
445  case DC1394_VIDEO_MODE_1024x768_YUV422:
446  case DC1394_VIDEO_MODE_1280x960_YUV422:
447  case DC1394_VIDEO_MODE_1600x1200_YUV422:
448  return YUV422_PACKED;
449 
450  case DC1394_VIDEO_MODE_640x480_YUV411:
451  return YUV411_PACKED;
452 
453 
454  case DC1394_VIDEO_MODE_640x480_RGB8:
455  case DC1394_VIDEO_MODE_800x600_RGB8:
456  case DC1394_VIDEO_MODE_1024x768_RGB8:
457  case DC1394_VIDEO_MODE_1280x960_RGB8:
458  case DC1394_VIDEO_MODE_1600x1200_RGB8:
459  return RGB;
460 
461  case DC1394_VIDEO_MODE_640x480_MONO8:
462  case DC1394_VIDEO_MODE_800x600_MONO8:
463  case DC1394_VIDEO_MODE_1024x768_MONO8:
464  case DC1394_VIDEO_MODE_1280x960_MONO8:
465  case DC1394_VIDEO_MODE_1600x1200_MONO8:
466  return MONO8;
467 
468  case DC1394_VIDEO_MODE_640x480_MONO16:
469  case DC1394_VIDEO_MODE_800x600_MONO16:
470  case DC1394_VIDEO_MODE_1024x768_MONO16:
471  case DC1394_VIDEO_MODE_1280x960_MONO16:
472  case DC1394_VIDEO_MODE_1600x1200_MONO16:
473  return MONO16;
474 
475  case DC1394_VIDEO_MODE_FORMAT7_0:
476  case DC1394_VIDEO_MODE_FORMAT7_1:
477  case DC1394_VIDEO_MODE_FORMAT7_2:
478  case DC1394_VIDEO_MODE_FORMAT7_3:
479  case DC1394_VIDEO_MODE_FORMAT7_4:
480  case DC1394_VIDEO_MODE_FORMAT7_5:
481  case DC1394_VIDEO_MODE_FORMAT7_6:
482  case DC1394_VIDEO_MODE_FORMAT7_7:
483  switch (_format7_coding) {
484  case DC1394_COLOR_CODING_MONO8:
485  return MONO8;
486  case DC1394_COLOR_CODING_YUV411:
487  return YUV411_PACKED;
488  case DC1394_COLOR_CODING_YUV422:
489  return YUV422_PACKED;
490  case DC1394_COLOR_CODING_RGB8:
491  return RGB;
492  case DC1394_COLOR_CODING_MONO16:
493  return MONO16;
494  case DC1394_COLOR_CODING_RAW8:
495  return RAW8;
496  case DC1394_COLOR_CODING_RAW16:
497  return RAW16;
498  default:
499  return CS_UNKNOWN;
500  }
501  break;
502 
503  default:
504  return CS_UNKNOWN;
505  }
506 }
507 
508 
509 bool
510 FirewireCamera::ready()
511 {
512  return _started;
513 }
514 
515 
516 void
517 FirewireCamera::set_image_number(unsigned int n)
518 {
519 }
520 
521 
522 /* CAMERA CONTROL STUFF */
523 
524 void
525 FirewireCamera::set_auto_focus(bool enabled)
526 {
527  dc1394error_t err;
528  if ((err = dc1394_feature_set_mode(_camera, DC1394_FEATURE_FOCUS,
529  enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL))
530  == DC1394_SUCCESS) {
531  _auto_focus = enabled;
532  } else {
533  throw Exception("FirewireCamera(%s): Setting auto focus failed (%s)", _model,
534  dc1394_error_get_string(err));
535  }
536 }
537 
538 
539 bool
540 FirewireCamera::auto_focus()
541 {
542  return _auto_focus;
543 }
544 
545 
546 unsigned int
547 FirewireCamera::focus()
548 {
549  unsigned int focus = 0;
550  if (dc1394_feature_get_value(_camera, DC1394_FEATURE_FOCUS, &focus) == DC1394_SUCCESS) {
551  return focus;
552  } else {
553  return 0;
554  }
555 
556 }
557 
558 
559 void
560 FirewireCamera::set_focus(unsigned int focus)
561 {
562  dc1394_feature_set_value(_camera, DC1394_FEATURE_FOCUS, focus);
563 }
564 
565 
566 unsigned int
567 FirewireCamera::focus_min()
568 {
569  unsigned int min = 0;
570  unsigned int max = 0;
571  if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_FOCUS, &min, &max) == DC1394_SUCCESS) {
572  return min;
573  } else {
574  return 0;
575  }
576 }
577 
578 
579 unsigned int
580 FirewireCamera::focus_max()
581 {
582  unsigned int max = 0;
583  unsigned int min = 0;
584  if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_FOCUS, &min, &max) == DC1394_SUCCESS) {
585  return max;
586  } else {
587  return 0;
588  }
589 }
590 
591 
592 /** Set status of auto shutter.
593  * @param enabled true to enable auto shutter, false to disable.
594  */
595 void
596 FirewireCamera::set_auto_shutter(bool enabled)
597 {
598  if (dc1394_feature_set_mode(_camera, DC1394_FEATURE_SHUTTER,
599  enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL)
600  == DC1394_SUCCESS) {
601  _auto_shutter = enabled;
602  }
603 }
604 
605 
606 /** Get status of auto shutter.
607  * @return true if auto shutter is enabled, false otherwise
608  */
609 bool
610 FirewireCamera::auto_shutter()
611 {
612  return _auto_shutter;
613 }
614 
615 
616 /** Set shutter value.
617  * @param shutter shutter value
618  */
619 void
620 FirewireCamera::set_shutter(unsigned int shutter)
621 {
622  if ( dc1394_feature_set_value(_camera, DC1394_FEATURE_SHUTTER, shutter) != DC1394_SUCCESS ) {
623  throw Exception("Failed to set shutter to %d", shutter);
624  }
625 }
626 
627 
628 /** Get shutter value.
629  * @return the current shutter value
630  */
631 unsigned int
632 FirewireCamera::shutter()
633 {
634  if ( dc1394_feature_get_value(_camera, DC1394_FEATURE_SHUTTER, &_shutter) != DC1394_SUCCESS ) {
635  throw Exception("Failed to retrieve shutter value");
636  }
637 
638  return _shutter;
639 }
640 
641 
642 /** Set status of auto white balance.
643  * @param enabled true to enable auto white balance, false to disable.
644  */
645 void
646 FirewireCamera::set_auto_white_balance(bool enabled)
647 {
648  if (dc1394_feature_set_mode(_camera, DC1394_FEATURE_WHITE_BALANCE,
649  enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL)
650  == DC1394_SUCCESS) {
651  _auto_white_balance = enabled;
652  }
653 }
654 
655 
656 /** Get status of auto white balance.
657  * @return true if white balance is enabled, false otherwise
658  */
659 bool
660 FirewireCamera::auto_white_balance()
661 {
662  return _auto_white_balance;
663 }
664 
665 
666 /** Get white balance values.
667  * @param ub contains U/B value upon return
668  * @param vr contains V/R value upon return
669  */
670 void
671 FirewireCamera::white_balance(unsigned int *ub, unsigned int *vr)
672 {
673  if ( dc1394_feature_whitebalance_get_value(_camera, &_white_balance_ub, &_white_balance_vr) != DC1394_SUCCESS ) {
674  throw Exception("Failed to retrieve white balance values");
675  }
676 
677  *ub = _white_balance_ub;
678  *vr = _white_balance_vr;
679 }
680 
681 
682 /** Set white balance values.
683  * @param ub U/B value
684  * @param vr V/R value
685  */
686 void
687 FirewireCamera::set_white_balance(unsigned int ub, unsigned int vr)
688 {
689  if ( dc1394_feature_whitebalance_set_value(_camera, ub, vr) != DC1394_SUCCESS ) {
690  throw Exception("Failed to set white balance to ub=%d vr=%d", ub, vr);
691  }
692 }
693 
694 /** Set the gain.
695  * @param gain the gain value
696  */
697 void
698 FirewireCamera::set_gain(unsigned int gain)
699 {
700  uint32_t min;
701  uint32_t max;
702  if ( dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_GAIN, &min, &max) != DC1394_SUCCESS ) {
703  throw Exception("Failed to get boundaries for feature gain");
704  }
705  if (gain < min) {
706  gain = min;
707  }
708  if (max < gain) {
709  gain = max;
710  }
711  if ( dc1394_feature_set_mode( _camera, DC1394_FEATURE_GAIN, DC1394_FEATURE_MODE_MANUAL ) != DC1394_SUCCESS ) {
712  throw Exception("Failed to set manual mode for feature gain");
713  }
714  if ( dc1394_feature_set_value( _camera, DC1394_FEATURE_GAIN, gain ) != DC1394_SUCCESS) {
715  throw Exception("Failed to set value for feature gain");
716  }
717 }
718 
719 /** Parse focus and set value.
720  * Parses the given string for a valid focus value and sets it.
721  * @param focus string representation of value
722  */
723 void
724 FirewireCamera::parse_set_focus(const char *focus)
725 {
726  string f = focus;
727  if ( f == "auto" ) {
728  _auto_focus = true;
729  } else if ( f == "manual" ) {
730  _auto_focus = false;
731  } else {
732  char *endptr = NULL;
733  long int focus = strtol(f.c_str(), &endptr, 10);
734  if ( endptr[0] != 0 ) {
735  throw TypeMismatchException("Focus value is invalid. String to int conversion failed");
736  } else if ( focus < 0 ) {
737  throw OutOfBoundsException("'Focus value < 0", focus, 0, 0xFFFFFFFF);
738  }
739  _auto_focus = false;
740  _focus = focus;
741  _do_set_focus = true;
742  }
743 }
744 
745 
746 /** Parse white balance and set value.
747  * Parses the given string for a valid white balance value and sets it.
748  * @param white_balance string representation of value
749  */
750 void
751 FirewireCamera::parse_set_white_balance(const char *white_balance)
752 {
753  string w = white_balance;
754  if ( w == "auto" ) {
755  _auto_white_balance = true;
756  } else {
757  // try to parse U/V values
758  string::size_type commapos = w.find(",", 0);
759  if ( commapos == string::npos ) {
760  throw Exception("Illegal white balance value, neither auto and no comma found");
761  }
762  string ub = w.substr(0, commapos);
763  string vr = w.substr(commapos + 1);
764  char *endptr;
765  long int ub_i = strtol(ub.c_str(), &endptr, 10);
766  if ( endptr[0] != 0 ) {
767  throw TypeMismatchException("White balance value for U/B is invalid. "
768  "String to int conversion failed");
769  } else if ( ub_i < 0 ) {
770  throw OutOfBoundsException("White balance value for U/B < 0", ub_i, 0, 0xFFFFFFFF);
771  }
772  long int vr_i = strtol(vr.c_str(), &endptr, 10);
773  if ( endptr[0] != 0 ) {
774  throw TypeMismatchException("White balance value for V/R is invalid. "
775  "String to int conversion failed");
776  } else if ( vr_i < 0 ) {
777  throw OutOfBoundsException("White balance value for V/R < 0", vr_i, 0, 0xFFFFFFFF);
778  }
779 
780  _auto_white_balance = false;
781  _white_balance_ub = ub_i;
782  _white_balance_vr = vr_i;
783  _do_set_white_balance = true;
784  }
785 }
786 
787 
788 /** Parse shutter and set value.
789  * Parses the given string for a valid shutter value and sets it.
790  * @param shutter string representation of value
791  */
792 void
793 FirewireCamera::parse_set_shutter(const char *shutter)
794 {
795  string s = shutter;
796  if ( s == "auto" ) {
797  _auto_shutter = true;
798  } else {
799  char *endptr;
800  long int tmp = strtol(s.c_str(), &endptr, 10);
801  if ( endptr[0] != '\0' ) {
802  throw TypeMismatchException("Shutter value is invalid. "
803  "String to int conversion failed");
804  } else if ( tmp < 0 ) {
805  throw OutOfBoundsException("Shutter value < 0", tmp, 0, 0xFFFFFFFF);
806  }
807  _auto_shutter = false;
808  _shutter = tmp;
809  _do_set_shutter = true;
810  }
811 }
812 
813 /** Constructor.
814  * Initialize and take parameters from camera argument parser. The following
815  * arguments are supported:
816  * - mode=MODE where MODE is one of
817  * - 640x480_YUV422
818  * - 640x480_MONO16
819  * - FORMAT7_0
820  * - FORMAT7_1
821  * - FORMAT7_2
822  * - FORMAT7_3
823  * - FORMAT7_4
824  * - FORMAT7_5
825  * - FORMAT7_6
826  * - FORMAT7_7
827  * - coding=CODING, color coding for Format7, CODING is one of:
828  * - YUV422
829  * - MONO8
830  * - MONO16
831  * - RAW16
832  * - isospeed=SPEED, ISO speed, SPEED is one of:
833  * - 400
834  * - 800
835  * - framerate=FPS, desired rate in frames per second, FPS is one of:
836  * - 15
837  * - 30
838  * - 60
839  * - 120
840  * - nbufs=NBUFS, number of DMA buffers, integer, 0 < n <= 32
841  * - width=WIDTH, width in pixels of Format7 ROI
842  * - height=HEIGHT, height in pixels of Format7 ROI
843  * - startx=STARTX, X start of Format7 ROI
844  * - starty=STARTY, Y start of Format7 ROI
845  * - packetsize=BYTES, packet size in BYTES
846  * - white_balance=(auto|U,V), white balance value, either auto for auto white balance
847  * or U/B and V/R values for adjustment
848  * - shutter=auto, determine the shutter time automatically
849  * - focus=MODE, MODE is either auto for auto focus, manual for manual focus without
850  * actually setting (for example set from external application) or a
851  * number for the focus.
852  * @param cap camera argument parser
853  */
854 FirewireCamera::FirewireCamera(const CameraArgumentParser *cap)
855 {
856  _started = _opened = false;
857  _valid_frame_received = false;
858  _auto_focus = true; // assume auto_focus, checked in open()
859  _auto_shutter = false;
860  _auto_white_balance = false;
861  _white_balance_ub = 0xFFFFFFFF;
862  _white_balance_vr = 0xFFFFFFFF;
863  _do_set_shutter = false;
864  _do_set_white_balance = false;
865  _do_set_focus = false;
866 
867  // Defaults
868  _mode = DC1394_VIDEO_MODE_640x480_YUV422;
869  _speed = DC1394_ISO_SPEED_400;
870  _framerate = DC1394_FRAMERATE_15;
871  _camera = NULL;
872  _dc1394 = NULL;
873  _format7_mode_enabled = false;
874  _format7_width = _format7_height = _format7_startx = _format7_starty = 0;
875  _format7_bpp = 4096;
876  _model = strdup(cap->cam_id().c_str());
877  _num_buffers = 8;
878  _shutter = 0;
879  _auto_gain = true;
880  _gain = 0;
881 
882  if ( cap->has("mode") ) {
883  string m = cap->get("mode");
884  if ( m == "640x480_MONO16" ) {
885  _mode = DC1394_VIDEO_MODE_640x480_MONO16;
886  } else if ( m == "FORMAT7_0" ) {
887  _mode = DC1394_VIDEO_MODE_FORMAT7_0;
888  _format7_mode_enabled = true;
889  } else if ( m == "FORMAT7_1" ) {
890  _mode = DC1394_VIDEO_MODE_FORMAT7_1;
891  _format7_mode_enabled = true;
892  } else if ( m == "FORMAT7_2" ) {
893  _mode = DC1394_VIDEO_MODE_FORMAT7_2;
894  _format7_mode_enabled = true;
895  } else if ( m == "FORMAT7_3" ) {
896  _mode = DC1394_VIDEO_MODE_FORMAT7_3;
897  _format7_mode_enabled = true;
898  } else if ( m == "FORMAT7_4" ) {
899  _mode = DC1394_VIDEO_MODE_FORMAT7_4;
900  _format7_mode_enabled = true;
901  } else if ( m == "FORMAT7_5" ) {
902  _mode = DC1394_VIDEO_MODE_FORMAT7_5;
903  _format7_mode_enabled = true;
904  } else if ( m == "FORMAT7_6" ) {
905  _mode = DC1394_VIDEO_MODE_FORMAT7_6;
906  _format7_mode_enabled = true;
907  } else if ( m == "FORMAT7_7" ) {
908  _mode = DC1394_VIDEO_MODE_FORMAT7_7;
909  _format7_mode_enabled = true;
910  }
911  }
912  if ( cap->has("coding") ) {
913  string c = cap->get("coding");
914  if ( c == "YUV422" ) {
915  _format7_coding = DC1394_COLOR_CODING_YUV422;
916  } else if ( c == "MONO8" ) {
917  _format7_coding = DC1394_COLOR_CODING_MONO8;
918  } else if ( c == "MONO16" ) {
919  _format7_coding = DC1394_COLOR_CODING_MONO16;
920  } else if ( c == "RAW16" ) {
921  _format7_coding = DC1394_COLOR_CODING_RAW16;
922  }
923  }
924  if ( cap->has("isospeed") ) {
925  string s = cap->get("isospeed");
926  if ( s == "400" ) {
927  _speed = DC1394_ISO_SPEED_400;
928  } else if ( s == "800" ) {
929  _speed = DC1394_ISO_SPEED_800;
930  }
931  }
932  if ( cap->has("framerate") ) {
933  string f = cap->get("framerate");
934  if ( f == "1.875" ) {
935  _framerate = DC1394_FRAMERATE_1_875;
936  } else if ( f == "3.75" ) {
937  _framerate = DC1394_FRAMERATE_3_75;
938  } else if ( f == "7.5" ) {
939  _framerate = DC1394_FRAMERATE_7_5;
940  } else if ( f == "15" ) {
941  _framerate = DC1394_FRAMERATE_15;
942  } else if ( f == "30" ) {
943  _framerate = DC1394_FRAMERATE_30;
944  } else if ( f == "60" ) {
945  _framerate = DC1394_FRAMERATE_60;
946  } else if ( f == "120" ) {
947  _framerate = DC1394_FRAMERATE_120;
948  } else if ( f == "240" ) {
949  _framerate = DC1394_FRAMERATE_240;
950  }
951  }
952  if ( cap->has("focus") ) {
953  parse_set_focus(cap->get("focus").c_str());
954  }
955  if ( cap->has("nbufs") ) {
956  _num_buffers = atoi(cap->get("nbufs").c_str());
957  }
958  if ( cap->has("width") ) {
959  _format7_width = atoi(cap->get("width").c_str());
960  }
961  if ( cap->has("height") ) {
962  _format7_height = atoi(cap->get("height").c_str());
963  }
964  if ( cap->has("startx") ) {
965  _format7_startx = atoi(cap->get("startx").c_str());
966  }
967  if ( cap->has("starty") ) {
968  _format7_starty = atoi(cap->get("starty").c_str());
969  }
970  if ( cap->has("packetsize") ) {
971  string p = cap->get("packetsize");
972  if ( p == "recommended" ) {
973  _format7_bpp = 0;
974  } else {
975  _format7_bpp = atoi(p.c_str());
976  }
977  }
978  if ( cap->has("gain") ) {
979  string g = cap->get("gain");
980  if ( g != "auto" ) {
981  _gain = atoi(g.c_str());
982  _auto_gain = false;
983  }
984  }
985  if ( cap->has("white_balance") ) {
986  parse_set_white_balance(cap->get("white_balance").c_str());
987  }
988  if ( cap->has("shutter") ) {
989  parse_set_shutter(cap->get("shutter").c_str());
990  }
991 }
992 
993 
994 /** Print list of cameras.
995  * Prints a list of available cameras to stdout.
996  */
997 void
998 FirewireCamera::print_available_fwcams()
999 {
1000 
1001  dc1394_t *dc1394 = dc1394_new();
1002  dc1394camera_list_t *list;
1003  dc1394error_t err;
1004  if ( (err = dc1394_camera_enumerate(dc1394, &list)) != DC1394_SUCCESS ) {
1005  throw Exception("Could not enumerate cameras: %s", dc1394_error_get_string(err));
1006  }
1007 
1008  if (list->num > 0) {
1009  for (unsigned int i = 0; i < list->num; ++i) {
1010  dc1394camera_t *tmpcam = dc1394_camera_new(dc1394, list->ids[i].guid);
1011  dc1394_camera_print_info(tmpcam, stdout);
1012  dc1394_camera_free(tmpcam);
1013  }
1014  } else {
1015  printf("Could not find any cameras\n");
1016  }
1017 }
1018 
1019 } // end namespace firevision
std::string get(std::string s) const
Get the value of the given parameter.
Definition: camargp.cpp:164
Fawkes library namespace.
Capturing a frame failed.
STL namespace.
Camera argument parser.
Definition: camargp.h:38
Base class for exceptions in Fawkes.
Definition: exception.h:36
Index out of bounds.
Definition: software.h:88
bool has(std::string s) const
Check if an parameter was given.
Definition: camargp.cpp:152
std::string cam_id() const
Get camera ID.
Definition: camargp.cpp:139