26 #include <core/exception.h>
27 #include <core/exceptions/software.h>
28 #include <dc1394/utils.h>
29 #include <fvcams/cam_exceptions.h>
30 #include <fvutils/system/camargp.h>
31 #include <utils/system/console_colors.h>
41 namespace firevision {
56 FirewireCamera::FirewireCamera(dc1394framerate_t framerate,
57 dc1394video_mode_t mode,
61 _started = _opened =
false;
62 _valid_frame_received =
false;
64 _auto_shutter =
false;
65 _auto_white_balance =
false;
67 _num_buffers = num_buffers;
69 _framerate = framerate;
70 _white_balance_ub = 0xFFFFFFFF;
71 _white_balance_vr = 0xFFFFFFFF;
72 _format7_mode_enabled =
false;
73 _format7_width = _format7_height = _format7_startx = _format7_starty = 0;
75 _model = strdup(
"any");
76 _do_set_shutter =
false;
77 _do_set_white_balance =
false;
78 _do_set_focus =
false;
85 if ((mode == DC1394_VIDEO_MODE_640x480_YUV422) && (framerate == DC1394_FRAMERATE_30)) {
87 _framerate = DC1394_FRAMERATE_15;
92 FirewireCamera::~FirewireCamera()
94 FirewireCamera::close();
105 FirewireCamera::open_device()
107 _dc1394 = dc1394_new();
108 dc1394camera_list_t *list;
110 if (dc1394_camera_enumerate(_dc1394, &list) != DC1394_SUCCESS) {
111 throw Exception(
"Could not enumerate cameras");
115 if (strcmp(_model,
"any") == 0) {
117 _camera = dc1394_camera_new(_dc1394, list->ids[0].guid);
119 dc1394_free(_dc1394);
121 throw Exception(
"Could not create camera for first foiund camera");
125 for (
unsigned int i = 0; i < list->num; ++i) {
126 dc1394camera_t *tmpcam = dc1394_camera_new(_dc1394, list->ids[i].guid);
127 if (strcmp(_model, tmpcam->model) == 0) {
132 dc1394_camera_free(tmpcam);
135 if (_camera == NULL) {
136 throw Exception(
"Could not find camera with model %s", _model);
143 _device_opened =
true;
147 FirewireCamera::open()
152 if (!_device_opened) {
158 if (iso_mode_enabled()) {
159 dc1394_video_set_transmission(_camera, DC1394_OFF);
163 dc1394_iso_release_bandwidth(_camera, INT_MAX);
164 for (
int channel = 0; channel < 64; ++channel) {
165 dc1394_iso_release_channel(_camera, channel);
170 if (_camera->bmode_capable > 0) {
171 dc1394_video_set_operation_mode(_camera, DC1394_OPERATION_MODE_1394B);
174 ((err = dc1394_video_set_iso_speed(_camera, _speed)) != DC1394_SUCCESS)
175 || ((err = dc1394_video_set_mode(_camera, _mode)) != DC1394_SUCCESS)
176 || ((err = dc1394_video_set_framerate(_camera, _framerate)) != DC1394_SUCCESS)) {
177 throw Exception(
"Setting up the camera failed: %s", dc1394_error_get_string(err));
180 if (_format7_mode_enabled) {
181 if (_format7_bpp == 0) {
183 dc1394_format7_get_recommended_packet_size(_camera, _mode, &rps);
187 if (((err = dc1394_format7_set_image_size(_camera, _mode, _format7_width, _format7_height))
190 dc1394_format7_set_image_position(_camera, _mode, _format7_startx, _format7_starty))
192 || ((err = dc1394_format7_set_color_coding(_camera, _mode, _format7_coding))
194 || ((err = dc1394_format7_set_packet_size(_camera, _mode, _format7_bpp))
195 != DC1394_SUCCESS)) {
196 throw Exception(
"Could not setup Format7 parameters: %s", dc1394_error_get_string(err));
200 set_auto_shutter(_auto_shutter);
201 if (!_auto_shutter && _do_set_shutter) {
202 set_shutter(_shutter);
205 set_auto_focus(_auto_focus);
206 if (!_auto_focus && _do_set_focus) {
210 set_auto_white_balance(_auto_white_balance);
211 if (!_auto_white_balance && (_white_balance_ub != 0xFFFFFFFF) && (_white_balance_vr != 0xFFFFFFFF)
212 && _do_set_white_balance) {
213 set_white_balance(_white_balance_ub, _white_balance_vr);
224 FirewireCamera::start()
230 throw Exception(
"FirewireCamera: Cannot start closed camera");
234 if ((err = dc1394_capture_setup(_camera, _num_buffers, DC1394_CAPTURE_FLAGS_DEFAULT))
236 dc1394_capture_stop(_camera);
237 throw Exception(
"FirewireCamera: Could not setup capture (%s)", dc1394_error_get_string(err));
240 if ((err = dc1394_video_set_transmission(_camera, DC1394_ON)) != DC1394_SUCCESS) {
242 dc1394_capture_stop(_camera);
243 throw Exception(
"FirewireCamera: Could not start ISO transmission (%s)",
244 dc1394_error_get_string(err));
254 FirewireCamera::stop()
257 dc1394_video_set_transmission(_camera, DC1394_OFF);
258 dc1394_capture_stop(_camera);
268 FirewireCamera::iso_mode_enabled()
270 dc1394switch_t status;
271 if (dc1394_video_get_transmission(_camera, &status) != DC1394_SUCCESS) {
272 throw Exception(
"Could not get transmission status");
274 return (status == DC1394_ON);
279 FirewireCamera::print_info()
282 dc1394_camera_print_info(_camera, stdout);
285 printf(
"Parameters:\n"
286 "valid frame received: %i\n"
288 "auto shutter: %i (shutter value: %u)\n"
289 "auto white balance: %i (white balance value %u/%u)\n"
290 "do set shutter: %i do set white balance: %i\n",
291 _valid_frame_received,
298 _do_set_shutter =
false,
299 _do_set_white_balance =
false);
306 FirewireCamera::guid()
const
312 return _camera->guid;
319 FirewireCamera::model()
const
325 return _camera->model;
329 FirewireCamera::capture()
332 throw CaptureException(
"FirewireCamera(%s): cannot capture on closed camera", _model);
335 throw CaptureException(
"FirewireCamera(%s): cannot capture on stopped camera", _model);
338 if (!iso_mode_enabled()) {
339 throw CaptureException(
"FirewireCamera(%s): isochronous transfer not active", _model);
344 != (err = dc1394_capture_dequeue(_camera, DC1394_CAPTURE_POLICY_WAIT, &_frame))) {
345 _valid_frame_received =
false;
348 dc1394_error_get_string(err));
350 _valid_frame_received = (_frame != NULL);
355 FirewireCamera::flush()
364 FirewireCamera::buffer()
366 if (_valid_frame_received) {
367 return _frame->image;
374 FirewireCamera::buffer_size()
376 if (_valid_frame_received) {
377 return _frame->total_bytes;
384 FirewireCamera::close()
390 dc1394_camera_free(_camera);
392 dc1394_free(_dc1394);
400 FirewireCamera::dispose_buffer()
402 if (_valid_frame_received) {
403 dc1394_capture_enqueue(_camera, _frame);
408 FirewireCamera::pixel_width()
411 if (_valid_frame_received) {
412 return _frame->size[0];
414 unsigned int width, height;
416 if ((err = dc1394_get_image_size_from_video_mode(_camera, _mode, &width, &height))
418 throw Exception(
"FirewireCamera(%s): cannot get width (%s)",
420 dc1394_error_get_string(err));
430 FirewireCamera::pixel_height()
433 if (_valid_frame_received) {
434 return _frame->size[1];
436 unsigned int width, height;
438 if ((err = dc1394_get_image_size_from_video_mode(_camera, _mode, &width, &height))
440 throw Exception(
"FirewireCamera(%s): cannot get width (%s)",
442 dc1394_error_get_string(err));
452 FirewireCamera::colorspace()
456 case DC1394_VIDEO_MODE_320x240_YUV422:
457 case DC1394_VIDEO_MODE_640x480_YUV422:
458 case DC1394_VIDEO_MODE_800x600_YUV422:
459 case DC1394_VIDEO_MODE_1024x768_YUV422:
460 case DC1394_VIDEO_MODE_1280x960_YUV422:
461 case DC1394_VIDEO_MODE_1600x1200_YUV422:
return YUV422_PACKED;
463 case DC1394_VIDEO_MODE_640x480_YUV411:
return YUV411_PACKED;
465 case DC1394_VIDEO_MODE_640x480_RGB8:
466 case DC1394_VIDEO_MODE_800x600_RGB8:
467 case DC1394_VIDEO_MODE_1024x768_RGB8:
468 case DC1394_VIDEO_MODE_1280x960_RGB8:
469 case DC1394_VIDEO_MODE_1600x1200_RGB8:
return RGB;
471 case DC1394_VIDEO_MODE_640x480_MONO8:
472 case DC1394_VIDEO_MODE_800x600_MONO8:
473 case DC1394_VIDEO_MODE_1024x768_MONO8:
474 case DC1394_VIDEO_MODE_1280x960_MONO8:
475 case DC1394_VIDEO_MODE_1600x1200_MONO8:
return MONO8;
477 case DC1394_VIDEO_MODE_640x480_MONO16:
478 case DC1394_VIDEO_MODE_800x600_MONO16:
479 case DC1394_VIDEO_MODE_1024x768_MONO16:
480 case DC1394_VIDEO_MODE_1280x960_MONO16:
481 case DC1394_VIDEO_MODE_1600x1200_MONO16:
return MONO16;
483 case DC1394_VIDEO_MODE_FORMAT7_0:
484 case DC1394_VIDEO_MODE_FORMAT7_1:
485 case DC1394_VIDEO_MODE_FORMAT7_2:
486 case DC1394_VIDEO_MODE_FORMAT7_3:
487 case DC1394_VIDEO_MODE_FORMAT7_4:
488 case DC1394_VIDEO_MODE_FORMAT7_5:
489 case DC1394_VIDEO_MODE_FORMAT7_6:
490 case DC1394_VIDEO_MODE_FORMAT7_7:
491 switch (_format7_coding) {
492 case DC1394_COLOR_CODING_MONO8:
return MONO8;
493 case DC1394_COLOR_CODING_YUV411:
return YUV411_PACKED;
494 case DC1394_COLOR_CODING_YUV422:
return YUV422_PACKED;
495 case DC1394_COLOR_CODING_RGB8:
return RGB;
496 case DC1394_COLOR_CODING_MONO16:
return MONO16;
497 case DC1394_COLOR_CODING_RAW8:
return RAW8;
498 case DC1394_COLOR_CODING_RAW16:
return RAW16;
499 default:
return CS_UNKNOWN;
503 default:
return CS_UNKNOWN;
508 FirewireCamera::ready()
514 FirewireCamera::set_image_number(
unsigned int n)
521 FirewireCamera::set_auto_focus(
bool enabled)
525 dc1394_feature_set_mode(_camera,
526 DC1394_FEATURE_FOCUS,
527 enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL))
529 _auto_focus = enabled;
531 throw Exception(
"FirewireCamera(%s): Setting auto focus failed (%s)",
533 dc1394_error_get_string(err));
538 FirewireCamera::auto_focus()
544 FirewireCamera::focus()
546 unsigned int focus = 0;
547 if (dc1394_feature_get_value(_camera, DC1394_FEATURE_FOCUS, &focus) == DC1394_SUCCESS) {
555 FirewireCamera::set_focus(
unsigned int focus)
557 dc1394_feature_set_value(_camera, DC1394_FEATURE_FOCUS, focus);
561 FirewireCamera::focus_min()
563 unsigned int min = 0;
564 unsigned int max = 0;
565 if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_FOCUS, &min, &max) == DC1394_SUCCESS) {
573 FirewireCamera::focus_max()
575 unsigned int max = 0;
576 unsigned int min = 0;
577 if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_FOCUS, &min, &max) == DC1394_SUCCESS) {
588 FirewireCamera::set_auto_shutter(
bool enabled)
590 if (dc1394_feature_set_mode(_camera,
591 DC1394_FEATURE_SHUTTER,
592 enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL)
594 _auto_shutter = enabled;
602 FirewireCamera::auto_shutter()
604 return _auto_shutter;
611 FirewireCamera::set_shutter(
unsigned int shutter)
613 if (dc1394_feature_set_value(_camera, DC1394_FEATURE_SHUTTER, shutter) != DC1394_SUCCESS) {
614 throw Exception(
"Failed to set shutter to %d", shutter);
622 FirewireCamera::shutter()
624 if (dc1394_feature_get_value(_camera, DC1394_FEATURE_SHUTTER, &_shutter) != DC1394_SUCCESS) {
625 throw Exception(
"Failed to retrieve shutter value");
635 FirewireCamera::set_auto_white_balance(
bool enabled)
637 if (dc1394_feature_set_mode(_camera,
638 DC1394_FEATURE_WHITE_BALANCE,
639 enabled ? DC1394_FEATURE_MODE_AUTO : DC1394_FEATURE_MODE_MANUAL)
641 _auto_white_balance = enabled;
649 FirewireCamera::auto_white_balance()
651 return _auto_white_balance;
659 FirewireCamera::white_balance(
unsigned int *ub,
unsigned int *vr)
661 if (dc1394_feature_whitebalance_get_value(_camera, &_white_balance_ub, &_white_balance_vr)
663 throw Exception(
"Failed to retrieve white balance values");
666 *ub = _white_balance_ub;
667 *vr = _white_balance_vr;
675 FirewireCamera::set_white_balance(
unsigned int ub,
unsigned int vr)
677 if (dc1394_feature_whitebalance_set_value(_camera, ub, vr) != DC1394_SUCCESS) {
678 throw Exception(
"Failed to set white balance to ub=%d vr=%d", ub, vr);
686 FirewireCamera::set_gain(
unsigned int gain)
690 if (dc1394_feature_get_boundaries(_camera, DC1394_FEATURE_GAIN, &min, &max) != DC1394_SUCCESS) {
691 throw Exception(
"Failed to get boundaries for feature gain");
699 if (dc1394_feature_set_mode(_camera, DC1394_FEATURE_GAIN, DC1394_FEATURE_MODE_MANUAL)
701 throw Exception(
"Failed to set manual mode for feature gain");
703 if (dc1394_feature_set_value(_camera, DC1394_FEATURE_GAIN, gain) != DC1394_SUCCESS) {
704 throw Exception(
"Failed to set value for feature gain");
713 FirewireCamera::parse_set_focus(
const char *focus)
718 }
else if (f ==
"manual") {
721 char * endptr = NULL;
722 long int focus_value = strtol(f.c_str(), &endptr, 10);
723 if (endptr[0] != 0) {
725 }
else if (focus_value < 0) {
729 _focus = focus_value;
730 _do_set_focus =
true;
739 FirewireCamera::parse_set_white_balance(
const char *white_balance)
741 string w = white_balance;
743 _auto_white_balance =
true;
746 string::size_type commapos = w.find(
",", 0);
747 if (commapos == string::npos) {
748 throw Exception(
"Illegal white balance value, neither auto and no comma found");
750 string ub = w.substr(0, commapos);
751 string vr = w.substr(commapos + 1);
753 long int ub_i = strtol(ub.c_str(), &endptr, 10);
754 if (endptr[0] != 0) {
756 "String to int conversion failed");
757 }
else if (ub_i < 0) {
760 long int vr_i = strtol(vr.c_str(), &endptr, 10);
761 if (endptr[0] != 0) {
763 "String to int conversion failed");
764 }
else if (vr_i < 0) {
768 _auto_white_balance =
false;
769 _white_balance_ub = ub_i;
770 _white_balance_vr = vr_i;
771 _do_set_white_balance =
true;
780 FirewireCamera::parse_set_shutter(
const char *shutter)
784 _auto_shutter =
true;
787 long int tmp = strtol(s.c_str(), &endptr, 10);
788 if (endptr[0] !=
'\0') {
790 "String to int conversion failed");
791 }
else if (tmp < 0) {
794 _auto_shutter =
false;
796 _do_set_shutter =
true;
843 _started = _opened =
false;
844 _valid_frame_received =
false;
846 _auto_shutter =
false;
847 _auto_white_balance =
false;
848 _white_balance_ub = 0xFFFFFFFF;
849 _white_balance_vr = 0xFFFFFFFF;
850 _do_set_shutter =
false;
851 _do_set_white_balance =
false;
852 _do_set_focus =
false;
855 _mode = DC1394_VIDEO_MODE_640x480_YUV422;
856 _speed = DC1394_ISO_SPEED_400;
857 _framerate = DC1394_FRAMERATE_15;
860 _format7_mode_enabled =
false;
861 _format7_width = _format7_height = _format7_startx = _format7_starty = 0;
863 _model = strdup(cap->
cam_id().c_str());
869 if (cap->
has(
"mode")) {
870 string m = cap->
get(
"mode");
871 if (m ==
"640x480_MONO16") {
872 _mode = DC1394_VIDEO_MODE_640x480_MONO16;
873 }
else if (m ==
"FORMAT7_0") {
874 _mode = DC1394_VIDEO_MODE_FORMAT7_0;
875 _format7_mode_enabled =
true;
876 }
else if (m ==
"FORMAT7_1") {
877 _mode = DC1394_VIDEO_MODE_FORMAT7_1;
878 _format7_mode_enabled =
true;
879 }
else if (m ==
"FORMAT7_2") {
880 _mode = DC1394_VIDEO_MODE_FORMAT7_2;
881 _format7_mode_enabled =
true;
882 }
else if (m ==
"FORMAT7_3") {
883 _mode = DC1394_VIDEO_MODE_FORMAT7_3;
884 _format7_mode_enabled =
true;
885 }
else if (m ==
"FORMAT7_4") {
886 _mode = DC1394_VIDEO_MODE_FORMAT7_4;
887 _format7_mode_enabled =
true;
888 }
else if (m ==
"FORMAT7_5") {
889 _mode = DC1394_VIDEO_MODE_FORMAT7_5;
890 _format7_mode_enabled =
true;
891 }
else if (m ==
"FORMAT7_6") {
892 _mode = DC1394_VIDEO_MODE_FORMAT7_6;
893 _format7_mode_enabled =
true;
894 }
else if (m ==
"FORMAT7_7") {
895 _mode = DC1394_VIDEO_MODE_FORMAT7_7;
896 _format7_mode_enabled =
true;
899 if (cap->
has(
"coding")) {
900 string c = cap->
get(
"coding");
902 _format7_coding = DC1394_COLOR_CODING_YUV422;
903 }
else if (c ==
"MONO8") {
904 _format7_coding = DC1394_COLOR_CODING_MONO8;
905 }
else if (c ==
"MONO16") {
906 _format7_coding = DC1394_COLOR_CODING_MONO16;
907 }
else if (c ==
"RAW16") {
908 _format7_coding = DC1394_COLOR_CODING_RAW16;
911 if (cap->
has(
"isospeed")) {
912 string s = cap->
get(
"isospeed");
914 _speed = DC1394_ISO_SPEED_400;
915 }
else if (s ==
"800") {
916 _speed = DC1394_ISO_SPEED_800;
919 if (cap->
has(
"framerate")) {
920 string f = cap->
get(
"framerate");
922 _framerate = DC1394_FRAMERATE_1_875;
923 }
else if (f ==
"3.75") {
924 _framerate = DC1394_FRAMERATE_3_75;
925 }
else if (f ==
"7.5") {
926 _framerate = DC1394_FRAMERATE_7_5;
927 }
else if (f ==
"15") {
928 _framerate = DC1394_FRAMERATE_15;
929 }
else if (f ==
"30") {
930 _framerate = DC1394_FRAMERATE_30;
931 }
else if (f ==
"60") {
932 _framerate = DC1394_FRAMERATE_60;
933 }
else if (f ==
"120") {
934 _framerate = DC1394_FRAMERATE_120;
935 }
else if (f ==
"240") {
936 _framerate = DC1394_FRAMERATE_240;
939 if (cap->
has(
"focus")) {
940 parse_set_focus(cap->
get(
"focus").c_str());
942 if (cap->
has(
"nbufs")) {
943 _num_buffers = atoi(cap->
get(
"nbufs").c_str());
945 if (cap->
has(
"width")) {
946 _format7_width = atoi(cap->
get(
"width").c_str());
948 if (cap->
has(
"height")) {
949 _format7_height = atoi(cap->
get(
"height").c_str());
951 if (cap->
has(
"startx")) {
952 _format7_startx = atoi(cap->
get(
"startx").c_str());
954 if (cap->
has(
"starty")) {
955 _format7_starty = atoi(cap->
get(
"starty").c_str());
957 if (cap->
has(
"packetsize")) {
958 string p = cap->
get(
"packetsize");
959 if (p ==
"recommended") {
962 _format7_bpp = atoi(p.c_str());
965 if (cap->
has(
"gain")) {
966 string g = cap->
get(
"gain");
968 _gain = atoi(g.c_str());
972 if (cap->
has(
"white_balance")) {
973 parse_set_white_balance(cap->
get(
"white_balance").c_str());
975 if (cap->
has(
"shutter")) {
976 parse_set_shutter(cap->
get(
"shutter").c_str());
984 FirewireCamera::print_available_fwcams()
986 dc1394_t * dc1394 = dc1394_new();
987 dc1394camera_list_t *list;
989 if ((err = dc1394_camera_enumerate(dc1394, &list)) != DC1394_SUCCESS) {
990 throw Exception(
"Could not enumerate cameras: %s", dc1394_error_get_string(err));
994 for (
unsigned int i = 0; i < list->num; ++i) {
995 dc1394camera_t *tmpcam = dc1394_camera_new(dc1394, list->ids[i].guid);
996 dc1394_camera_print_info(tmpcam, stdout);
997 dc1394_camera_free(tmpcam);
1000 printf(
"Could not find any cameras\n");
Base class for exceptions in Fawkes.
std::string cam_id() const
Get camera ID.
bool has(std::string s) const
Check if an parameter was given.
std::string get(std::string s) const
Get the value of the given parameter.
Capturing a frame failed.
Fawkes library namespace.