00001
00002 #include <stdio.h>
00003 #include <iostream>
00004 #include <stdint.h>
00005 #include <stdlib.h>
00006 #include <inttypes.h>
00007
00008 #ifndef _WIN32
00009 #include <unistd.h>
00010 #endif
00011
00012 #include "dc1394vs.h"
00013
00014 using namespace std;
00015
00016 void DC1394Factory::registerParameters(ParamSection *sec) {
00017 sec->addBoolParam("useDC1394", &use, true);
00018 sec->addBoolParam("dc1394.debug", ¶ms.debug, false);
00019 sec->addBoolParam("dc1394.gray", ¶ms.gray, false);
00020 sec->addIntParam("dc1394.width", ¶ms.width, -1);
00021 sec->addIntParam("dc1394.height", ¶ms.height, -1);
00022 sec->addIntParam("dc1394.framerate", ¶ms.framerate, -1);
00023 sec->addIntParam("dc1394.bus_speed", ¶ms.bus_speed, -1);
00024 };
00025
00026 VideoSource *DC1394Factory::construct() {
00027 if (use) {
00028
00029 DC1394 *vs = new DC1394(params);
00030 if (vs->initialize()) return vs;
00031 delete vs;
00032 }
00033 return 0;
00034 }
00035
00036 DC1394::DC1394(Params &p) : params(p)
00037 {
00038 image =0;
00039 playing = false;
00040 camera = 0;
00041 frame=0;
00042 }
00043
00044 DC1394::~DC1394()
00045 {
00046 stop();
00047 if (image) cvReleaseImage(&image);
00048
00049 if (camera) {
00050 dc1394_video_set_transmission(camera, DC1394_OFF);
00051 dc1394_capture_stop(camera);
00052
00053 dc1394_free (d);
00054 }
00055 }
00056
00057 int DC1394::getChannels() {
00058 return 3;
00059 }
00060
00061 static const char *color_coding_name(dc1394color_coding_t a)
00062 {
00063 switch(a) {
00064 case DC1394_COLOR_CODING_MONO8: return "mono8";
00065 case DC1394_COLOR_CODING_YUV411 : return "yuv411";
00066 case DC1394_COLOR_CODING_YUV422 : return "yuv422";
00067 case DC1394_COLOR_CODING_YUV444 : return "yuv444";
00068 case DC1394_COLOR_CODING_RGB8 : return "rgb8";
00069 case DC1394_COLOR_CODING_MONO16 : return "mono16";
00070 case DC1394_COLOR_CODING_RGB16 : return "rgb16";
00071 case DC1394_COLOR_CODING_MONO16S : return "mono16s";
00072 case DC1394_COLOR_CODING_RGB16S : return "rgb16s";
00073 case DC1394_COLOR_CODING_RAW8 : return "raw8";
00074 case DC1394_COLOR_CODING_RAW16 : return "raw16";
00075 default: return "unknown color coding";
00076 }
00077 }
00078
00079 ostream & print_mode(ostream &stream, dc1394camera_t *camera, const dc1394video_mode_t m) {
00080 uint32_t x,y;
00081 dc1394color_coding_t nColourCoding;
00082 dc1394_get_image_size_from_video_mode(camera, m, &x, &y);
00083 dc1394_get_color_coding_from_video_mode(camera,m,&nColourCoding);
00084 stream << x << "x" <<y << " " << color_coding_name(nColourCoding);
00085 return stream;
00086 }
00087
00088 static void cleanup_and_exit(dc1394camera_t *camera)
00089 {
00090 dc1394_video_set_transmission(camera, DC1394_OFF);
00091 dc1394_capture_stop(camera);
00092 dc1394_camera_free(camera);
00093 }
00094
00095 bool DC1394::init_video_mode()
00096 {
00097
00098 dc1394video_modes_t modes;
00099 dc1394error_t error = dc1394_video_get_supported_modes(camera, &modes);
00100 if(error) { cerr << "Could not get modelist\n"; return false; }
00101
00102
00103 dc1394color_coding_t nTargetColourCoding = DC1394_COLOR_CODING_RGB8;
00104
00105
00106 if (params.debug) {
00107 cout << "DC1394: possible video modes:" << endl;
00108 }
00109
00110
00111 std::vector<dc1394video_mode_t> vModes;
00112 for(unsigned int i = 0; i < modes.num; i++)
00113 {
00114 dc1394video_mode_t nMode = modes.modes[i];
00115
00116 if(nMode >= DC1394_VIDEO_MODE_FORMAT7_0) continue;
00117 dc1394color_coding_t nColourCoding;
00118 error=dc1394_get_color_coding_from_video_mode(camera,nMode,&nColourCoding);
00119 if(error) {
00120 cerr << "Error in get_color_coding_from_video_mode\n";
00121 return false;
00122 }
00123 if(nColourCoding == nTargetColourCoding)
00124 vModes.push_back(nMode);
00125
00126 if (params.debug) {
00127 print_mode(cout << "\t", camera, nMode) << endl;
00128 }
00129 }
00130 if(vModes.size() == 0) {
00131 cerr << "No RGB video mode found for camera!\n";
00132 return false;
00133 }
00134
00135
00136 bool bModeFound = false;
00137 dc1394video_mode_t nMode;
00138 if(params.width>0) {
00139 for(size_t i = 0; i<vModes.size(); i++) {
00140 uint32_t x,y;
00141 dc1394_get_image_size_from_video_mode(camera, vModes[i], &x, &y);
00142
00143 if(x == (uint32_t) params.width && (params.height<0 || y == (uint32_t) params.height)) {
00144 bModeFound = true;
00145 nMode = vModes[i];
00146 break;
00147 }
00148 }
00149 if(!bModeFound) {
00150 cerr << "Video mode " << params.width << "x" << params.height << " not found!\n";
00151 }
00152 }
00153 if (!bModeFound) {
00154
00155
00156 sort(vModes.begin(), vModes.end());
00157 bModeFound = true;
00158 nMode = vModes.back();
00159 }
00160
00161
00162 uint32_t x,y;
00163 dc1394_get_image_size_from_video_mode(camera, nMode, &x, &y);
00164 width = x;
00165 height = y;
00166
00167
00168 dc1394framerates_t framerates;
00169 dc1394framerate_t nChosenFramerate = DC1394_FRAMERATE_MIN;
00170 error = dc1394_video_get_supported_framerates(camera,nMode,&framerates);
00171 if(error) { cerr << "Could not query supported framerates" << endl; return false; }
00172
00173 if (params.debug) {
00174 print_mode(cout << "Possible framerates for video mode ", camera, nMode) << ": ";
00175 for(unsigned int i=0; i<framerates.num; i++){
00176 float f_rate;
00177 dc1394_framerate_as_float(framerates.framerates[i],&f_rate);
00178 if (i) cout << ", ";
00179 cout << f_rate;
00180 }
00181 cout << endl;
00182 }
00183 if(params.framerate > 0)
00184 {
00185 for(unsigned int i=0; i<framerates.num; i++){
00186 float f_rate;
00187 dc1394_framerate_as_float(framerates.framerates[i],&f_rate);
00188 if(fabsf(f_rate - params.framerate) <= 1.0f){
00189 nChosenFramerate = framerates.framerates[i];
00190 break;
00191 }
00192 }
00193 }
00194 float best_frame_rate=0;
00195 if (nChosenFramerate == DC1394_FRAMERATE_MIN) {
00196
00197 for(unsigned int i=0; i<framerates.num; i++){
00198 float f_rate;
00199 dc1394_framerate_as_float(framerates.framerates[i],&f_rate);
00200 if(f_rate > best_frame_rate) {
00201 nChosenFramerate = framerates.framerates[i];
00202 best_frame_rate = f_rate;
00203 }
00204 }
00205 }
00206
00207
00208
00209 bool speed800=false;
00210 if (params.bus_speed <0 || params.bus_speed == 800) {
00211 error=dc1394_video_set_operation_mode(camera, DC1394_OPERATION_MODE_1394B);
00212 if (!error)
00213 speed800 = (error=dc1394_video_set_iso_speed(camera, DC1394_ISO_SPEED_800))==0;
00214 }
00215 if (!speed800) {
00216 error = dc1394_video_set_iso_speed(camera, DC1394_ISO_SPEED_400);
00217 }
00218 if(error) { cerr << "Could not set ISO speed." << endl; return false; }
00219
00220
00221
00222
00223 error = dc1394_video_set_mode(camera, nMode);
00224 if(error) { cerr << "Could not set video mode" << endl; return false; }
00225
00226 error = dc1394_video_set_framerate(camera, nChosenFramerate);
00227 if(error) { cerr << "Could not set frame-rate" << endl; return false; }
00228
00229 float fps;
00230 dc1394_framerate_as_float(nChosenFramerate,&fps);
00231 print_mode(cout << "DC1394: Video mode: ", camera, nMode) << " at " << fps << " fps."
00232 << " bus speed: " << (speed800 ? 800 : 400) << " Mbps.\n";
00233 dc1394_log_register_handler(DC1394_LOG_WARNING, 0, 0);
00234
00235 dc1394featureset_t features;
00236 dc1394_feature_get_all(camera, &features);
00237 if (params.debug) {
00238 dc1394_feature_print_all(&features, stdout);
00239 }
00240 return true;
00241 }
00242
00243
00244 #define CHECK_ERROR(err, clean, msg) if (err!=DC1394_SUCCESS) { std::cerr << msg << std::endl; clean ; return false; }
00245 bool DC1394::initialize()
00246 {
00247 d = dc1394_new ();
00248 if (!d)
00249 return false;
00250 dc1394camera_list_t * list;
00251 dc1394error_t err=dc1394_camera_enumerate (d, &list);
00252
00253 if (list->num == 0) {
00254 dc1394_free (d);
00255 return false;
00256 }
00257
00258 camera = dc1394_camera_new (d, list->ids[0].guid);
00259 dc1394_camera_free_list (list);
00260 if (!camera) {
00261 dc1394_log_error("Failed to initialize camera");
00262 dc1394_free (d);
00263 return false;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 if (!init_video_mode()) {
00284 cleanup_and_exit(camera);
00285 return false;
00286 }
00287 err=dc1394_capture_setup(camera,4, DC1394_CAPTURE_FLAGS_DEFAULT);
00288 CHECK_ERROR(err,cleanup_and_exit(camera),"Could not setup camera-\nmake sure that the video mode and framerate are\nsupported by your camera\n");
00289
00290
00291
00292
00293 playing = false;
00294 start();
00295
00296 return true;
00297 }
00298
00299
00300 bool DC1394::getFrame(IplImage *dst) {
00301
00302 assert(dst);
00303
00304 if (playing) {
00305
00306 if (frame)
00307 dc1394_capture_enqueue(camera, frame);
00308 dc1394error_t err=dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, &frame);
00309 if (err != DC1394_SUCCESS) return false;
00310
00311 }
00312 CvMat mat;
00313 cvInitMatHeader(&mat, height, width, CV_8UC3, frame->image);
00314
00315 if (((unsigned)dst->width == width)
00316 && ((unsigned)dst->height==height)
00317 && (dst->nChannels == 3))
00318 {
00319 cvCopy(&mat, dst);
00320 dst->channelSeq[0] = 'R';
00321 dst->channelSeq[1] = 'G';
00322 dst->channelSeq[2] = 'B';
00323 } else if (dst->nChannels == 3) {
00324 cvResize(&mat, dst);
00325 dst->channelSeq[0] = 'R';
00326 dst->channelSeq[1] = 'G';
00327 dst->channelSeq[2] = 'B';
00328 } else if (((unsigned)dst->width == width)
00329 && ((unsigned)dst->height==height)
00330 && (dst->nChannels == 1))
00331 {
00332 cvCvtColor(&mat, dst, CV_RGB2GRAY);
00333 } else {
00334 std::cout << "DC1394: image format conversion not implemented !\n";
00335 std::cout << "Trying " << dst->width << "x"<<dst->height << "x"<<dst->nChannels
00336 << " against " << width << "x" << height << "x3" << std::endl;
00337 }
00338
00339 return true;
00340 }
00341
00342
00343 void DC1394::getSize(int &w, int &h)
00344 {
00345 w = width;
00346 h = height;
00347 }
00348
00349 void DC1394::start()
00350 {
00351 if (playing) return;
00352
00353 if (dc1394_video_set_transmission(camera, DC1394_ON)!=DC1394_SUCCESS)
00354 {
00355
00356 fprintf( stderr, "unable to start camera iso transmission\n");
00357 }
00358
00359 playing = true;
00360 }
00361
00362 void DC1394::stop()
00363 {
00364 if (playing == false) return;
00365 dc1394_video_set_transmission(camera, DC1394_OFF);
00366 playing = false;
00367 }
00368
00369
00370