00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Devices/IEEE1394grabber.H"
00039
00040 #include "Component/OptionManager.H"
00041 #include "Devices/DeviceOpts.H"
00042 #include "Image/Image.H"
00043 #include "Image/Pixels.H"
00044 #include "Raster/GenericFrame.H"
00045 #include "Util/Assert.H"
00046 #include "Util/SimTime.H"
00047 #include "Util/sformat.H"
00048 #include "Video/VideoFrame.H"
00049
00050 #ifdef HAVE_IEEE1394
00051 #include <libraw1394/raw1394.h>
00052 #endif
00053 #include <unistd.h>
00054
00055
00056 #define IEEE1394WAIT 1
00057
00058
00059
00060
00061
00062 namespace
00063 {
00064
00065 #ifdef HAVE_IEEE1394
00066
00067 struct CameraModeInfo
00068 {
00069 VideoFormat vidfmt;
00070 int w;
00071 int h;
00072 int dc1394mode;
00073 int dc1394format;
00074 };
00075
00076
00077
00078 void find1394mode(const VideoFormat vidfmt, const Dims& dims,
00079 int* dc1394mode, int* dc1394format)
00080 {
00081 static const CameraModeInfo modes[] =
00082 {
00083 { VIDFMT_YUV444, 160, 120, MODE_160x120_YUV444 , FORMAT_VGA_NONCOMPRESSED },
00084 { VIDFMT_YUV422, 320, 240, MODE_320x240_YUV422 , FORMAT_VGA_NONCOMPRESSED },
00085 { VIDFMT_YUV411, 640, 480, MODE_640x480_YUV411 , FORMAT_VGA_NONCOMPRESSED },
00086 { VIDFMT_YUV422, 640, 480, MODE_640x480_YUV422 , FORMAT_VGA_NONCOMPRESSED },
00087 { VIDFMT_RGB24, 640, 480, MODE_640x480_RGB , FORMAT_VGA_NONCOMPRESSED },
00088 { VIDFMT_GREY, 640, 480, MODE_640x480_MONO , FORMAT_VGA_NONCOMPRESSED },
00089 { VIDFMT_YUV422, 800, 600, MODE_800x600_YUV422 , FORMAT_SVGA_NONCOMPRESSED_1 },
00090 { VIDFMT_RGB24, 800, 600, MODE_800x600_RGB , FORMAT_SVGA_NONCOMPRESSED_1 },
00091 { VIDFMT_GREY, 800, 600, MODE_800x600_MONO , FORMAT_SVGA_NONCOMPRESSED_1 },
00092 { VIDFMT_YUV422, 1024, 768, MODE_1024x768_YUV422 , FORMAT_SVGA_NONCOMPRESSED_1 },
00093 { VIDFMT_RGB24, 1024, 768, MODE_1024x768_RGB , FORMAT_SVGA_NONCOMPRESSED_1 },
00094 { VIDFMT_GREY, 1024, 768, MODE_1024x768_MONO , FORMAT_SVGA_NONCOMPRESSED_1 },
00095 { VIDFMT_YUV422, 1280, 960, MODE_1280x960_YUV422 , FORMAT_SVGA_NONCOMPRESSED_2 },
00096 { VIDFMT_RGB24, 1280, 960, MODE_1280x960_RGB , FORMAT_SVGA_NONCOMPRESSED_2 },
00097 { VIDFMT_GREY, 1280, 960, MODE_1280x960_MONO , FORMAT_SVGA_NONCOMPRESSED_2 },
00098 { VIDFMT_YUV422, 1600, 1200, MODE_1600x1200_YUV422 , FORMAT_SVGA_NONCOMPRESSED_2 },
00099 { VIDFMT_RGB24, 1600, 1200, MODE_1600x1200_RGB , FORMAT_SVGA_NONCOMPRESSED_2 },
00100 { VIDFMT_GREY, 1600, 1200, MODE_1600x1200_MONO , FORMAT_SVGA_NONCOMPRESSED_2 }
00101 };
00102
00103 for (size_t i = 0; i < sizeof(modes) / sizeof(CameraModeInfo); ++i)
00104 {
00105 if (modes[i].vidfmt == vidfmt
00106 && modes[i].w == dims.w()
00107 && modes[i].h == dims.h())
00108 {
00109 *dc1394mode = modes[i].dc1394mode;
00110 *dc1394format = modes[i].dc1394format;
00111 return;
00112 }
00113 }
00114
00115 std::string msg =
00116 sformat("Unsupported resolution/format combination %s @ %dx%d"
00117 "\nSupported combinations are:",
00118 convertToString(vidfmt).c_str(), dims.w(), dims.h());
00119 for (size_t i = 0; i < sizeof(modes) / sizeof(CameraModeInfo); ++i)
00120 {
00121 msg += sformat("\n\t%7s @ %dx%d",
00122 convertToString(modes[i].vidfmt).c_str(),
00123 modes[i].w, modes[i].h);
00124 }
00125
00126 LFATAL("%s", msg.c_str());
00127 }
00128
00129 struct FramerateInfo
00130 {
00131 float fps;
00132 int dc1394framerate;
00133 };
00134
00135
00136 int find1394framerate(const float fps)
00137 {
00138 static const FramerateInfo framerates[] =
00139 {
00140 { 1.875F, FRAMERATE_1_875 },
00141 { 3.75F, FRAMERATE_3_75 },
00142 { 7.5F, FRAMERATE_7_5 },
00143 { 15.0F, FRAMERATE_15 },
00144 { 30.0F, FRAMERATE_30 },
00145 { 60.0F, FRAMERATE_60 }
00146 };
00147
00148 for (size_t i = 0; i < sizeof(framerates) / sizeof(FramerateInfo); ++i)
00149 if (framerates[i].fps == fps)
00150 return framerates[i].dc1394framerate;
00151
00152 std::string msg =
00153 sformat("Unsupported framerate %f fps"
00154 "\nSupported framerates are:", fps);
00155 for (size_t i = 0; i < sizeof(framerates) / sizeof(FramerateInfo); ++i)
00156 msg += sformat("\n\t%.3f fps", framerates[i].fps);
00157
00158 LFATAL("%s", msg.c_str());
00159 return -1;
00160 }
00161
00162 #endif // HAVE_IEEE1394
00163
00164 }
00165
00166
00167 IEEE1394grabber::IEEE1394grabber(OptionManager& mgr,
00168 const std::string& descrName,
00169 const std::string& tagName,
00170 const ParamFlag flags) :
00171 FrameIstream(mgr, descrName, tagName),
00172
00173
00174
00175
00176
00177 itsDevName(&OPT_FrameGrabberDevice, this, "/dev/video1394/0", flags),
00178 itsChannel(&OPT_FrameGrabberChannel, this, 0, flags),
00179 itsSubChan(&OPT_FrameGrabberSubChan, this, 0, flags),
00180 itsDims(&OPT_FrameGrabberDims, this, Dims(320, 240), flags),
00181 itsGrabMode(&OPT_FrameGrabberMode, this, VIDFMT_YUV422, flags),
00182 itsByteSwap(&OPT_FrameGrabberByteSwap, this, false, flags),
00183 itsFPS(&OPT_FrameGrabberFPS, this, 30.0, flags),
00184 itsNbuf(&OPT_FrameGrabberNbuf, this, 4, flags),
00185 itsBrightness(&OPT_FrameGrabberBrightness, this, 32768, flags | ALLOW_ONLINE_CHANGES),
00186 itsHue(&OPT_FrameGrabberHue, this, 32768, flags | ALLOW_ONLINE_CHANGES),
00187 itsSaturation(&OPT_FrameGrabberSaturation, this, 90, flags | ALLOW_ONLINE_CHANGES),
00188 itsExposure(&OPT_FrameGrabberExposure, this, 511, flags | ALLOW_ONLINE_CHANGES),
00189 itsSharpness(&OPT_FrameGrabberSharpness, this, 80, flags | ALLOW_ONLINE_CHANGES),
00190 itsWhiteBalBU(&OPT_FrameGrabberWhiteBalBU, this, 95, flags | ALLOW_ONLINE_CHANGES),
00191 itsWhiteBalRV(&OPT_FrameGrabberWhiteBalRV, this, 87, flags | ALLOW_ONLINE_CHANGES),
00192 itsGamma(&OPT_FrameGrabberGamma, this, 1, flags | ALLOW_ONLINE_CHANGES),
00193 itsShutter(&OPT_FrameGrabberShutter, this, 6, flags | ALLOW_ONLINE_CHANGES),
00194 itsGain(&OPT_FrameGrabberGain, this, 87, flags | ALLOW_ONLINE_CHANGES)
00195 #ifdef HAVE_IEEE1394
00196 ,itsCameraOk(false), itsHandle(NULL)
00197 #endif
00198 {
00199
00200 mgr.requestOptionAlias(&OPT_ALIAScamiSight);
00201 }
00202
00203
00204 void IEEE1394grabber::start1()
00205 {
00206 #ifndef HAVE_IEEE1394
00207 LFATAL("you must have ieee1394 (firewire) support and the libdc1394 "
00208 "library in order to use IEEE1394grabber");
00209 #else
00210 int ieeegrabmode, ieeegrabformat;
00211 find1394mode(itsGrabMode.getVal(), itsDims.getVal(),
00212 &ieeegrabmode, &ieeegrabformat);
00213
00214 const int framerate = find1394framerate(itsFPS.getVal());
00215
00216
00217 itsHandle = dc1394_create_handle(itsChannel.getVal());
00218 if (itsHandle == 0) LFATAL("Cannot create raw1394 handle");
00219
00220
00221 int nb = raw1394_get_nodecount(itsHandle);
00222 LDEBUG("Found %d nodes on port %d", nb, itsChannel.getVal());
00223 int nc;
00224 nodeid_t *node = dc1394_get_camera_nodes(itsHandle, &nc, 1);
00225 fflush(stdout);
00226 int subchan = itsSubChan.getVal();
00227 if (nc < 1) LFATAL("No camera on bus?");
00228 else LDEBUG("Found %d camera(s)", nc);
00229 if (subchan < 0 || subchan >= nc)
00230 LFATAL("Invalid camera number %d", subchan);
00231
00232
00233 if (node[subchan] == nb - 1)
00234 LFATAL("You need to insmod ohci1394 attempt_root=1");
00235
00236 #ifdef IEEE1394NEW
00237
00238 if (dc1394_dma_setup_capture(itsHandle, node[subchan], subchan,
00239 ieeegrabformat, ieeegrabmode,
00240 IEEE1394GRABSPEED, framerate,
00241 itsNbuf.getVal(), 0, 1,
00242 itsDevName.getVal().c_str(), &itsCam) !=
00243 DC1394_SUCCESS)
00244 LFATAL("Camera setup failed; see preceding error message from libdc1394.");
00245 #else
00246
00247 if (dc1394_dma_setup_capture(itsHandle, node[subchan], subchan,
00248 ieeegrabformat, ieeegrabmode,
00249 IEEE1394GRABSPEED, framerate,
00250 itsNbuf.getVal(), 1,
00251 itsDevName.getVal().c_str(), &itsCam) !=
00252 DC1394_SUCCESS)
00253 LFATAL("Camera setup failed; see preceding error message from libdc1394.");
00254 #endif
00255 itsCameraOk = true;
00256
00257
00258
00259 if( dc1394_set_brightness( itsHandle, itsCam.node,
00260 itsBrightness.getVal() ) != DC1394_SUCCESS )
00261 LERROR("Unable to set brightness");
00262 if( dc1394_set_exposure( itsHandle, itsCam.node,
00263 itsExposure.getVal() ) != DC1394_SUCCESS )
00264 LERROR("Unable to set exposure");
00265 if( dc1394_set_sharpness( itsHandle, itsCam.node,
00266 itsSharpness.getVal() ) != DC1394_SUCCESS )
00267 LERROR("Unable to set sharpness");
00268 if( dc1394_set_white_balance( itsHandle, itsCam.node,
00269 itsWhiteBalBU.getVal(),
00270 itsWhiteBalRV.getVal() ) != DC1394_SUCCESS )
00271 LERROR("Unable to set white balance");
00272 if( dc1394_set_hue( itsHandle, itsCam.node,
00273 itsHue.getVal() ) != DC1394_SUCCESS )
00274 LERROR("Unable to set hue");
00275 if( dc1394_set_saturation( itsHandle, itsCam.node,
00276 itsSaturation.getVal() ) != DC1394_SUCCESS )
00277 LERROR("Unable to set saturation");
00278 if( dc1394_set_gamma( itsHandle, itsCam.node,
00279 itsGamma.getVal() ) != DC1394_SUCCESS )
00280 LERROR("Unable to set gamma");
00281 if( dc1394_set_shutter( itsHandle, itsCam.node,
00282 itsShutter.getVal() ) != DC1394_SUCCESS )
00283 LERROR("Unable to set shutter");
00284 if( dc1394_set_gain( itsHandle, itsCam.node,
00285 itsGain.getVal() != DC1394_SUCCESS ) )
00286 LERROR("Unable to set gain");
00287
00288
00289 dc1394_feature_set features;
00290 if (dc1394_get_camera_feature_set(itsHandle, itsCam.node, &features)
00291 != DC1394_SUCCESS)
00292 LDEBUG("Unable to get camera feature set");
00293 else
00294 dc1394_print_feature_set(&features);
00295
00296
00297 quadlet_t val;
00298 if (dc1394_query_supported_formats(itsHandle, itsCam.node, &val) != DC1394_SUCCESS)
00299 LERROR("Cannot query supported formats");
00300 else
00301 LDEBUG("Supported formats: %lx", (unsigned long) val);
00302
00303 if (dc1394_query_supported_modes(itsHandle, itsCam.node, ieeegrabformat, &val)
00304 != DC1394_SUCCESS)
00305 LERROR("Cannot query supported modes");
00306 else
00307 LDEBUG("Supported modes for format %d: %lx",
00308 ieeegrabformat, (unsigned long) val);
00309
00310 if (dc1394_query_supported_framerates(itsHandle, itsCam.node,
00311 ieeegrabformat, ieeegrabmode, &val)
00312 != DC1394_SUCCESS)
00313 LERROR("Cannot query supported framerates");
00314 else
00315 LDEBUG("Supported framerates for format %d, mode %d: %lx",
00316 ieeegrabformat, ieeegrabmode, (unsigned long) val);
00317
00318
00319 if (dc1394_start_iso_transmission(itsHandle, itsCam.node) != DC1394_SUCCESS)
00320 LFATAL("Cannot start data transmission");
00321
00322
00323 unsigned int ret;
00324 if (dc1394_get_video_format(itsHandle, itsCam.node, &ret) != DC1394_SUCCESS)
00325 LERROR("Cannot get video format");
00326 else
00327 LDEBUG("Current video format: %x", ret);
00328
00329 if (dc1394_get_video_mode(itsHandle, itsCam.node, &ret) != DC1394_SUCCESS)
00330 LERROR("Cannot get video mode");
00331 else
00332 LDEBUG("Current video mode: %x", ret);
00333
00334 if (dc1394_get_video_framerate(itsHandle, itsCam.node, &ret) != DC1394_SUCCESS)
00335 LERROR("Cannot get video framerate");
00336 else
00337 LDEBUG("Current video framerate: %x", ret);
00338
00339 unsigned int ret2;
00340 if (dc1394_get_iso_channel_and_speed(itsHandle, itsCam.node, &ret, &ret2)
00341 != DC1394_SUCCESS)
00342 LERROR("Cannot get ISO channel and speed");
00343 else
00344 LDEBUG("Current ISO channel: %x, speed: %x", ret, ret2);
00345
00346 dc1394bool_t ison;
00347 if (dc1394_get_iso_status(itsHandle, itsCam.node, &ison) != DC1394_SUCCESS)
00348 LERROR("Cannot check whether ISO transmission on");
00349 else
00350 LDEBUG("ISO transmission on: %d", ison);
00351
00352 LINFO("Initialization complete and ISO transmission under way...");
00353 #endif // HAVE_IEEE1394
00354 }
00355
00356
00357 void IEEE1394grabber::stop2()
00358 {
00359 #ifndef HAVE_IEEE1394
00360
00361 LERROR("you must have ieee1394 (firewire) support and the libdc1394 "
00362 "library in order to use IEEE1394grabber");
00363 #else
00364 if (itsCameraOk)
00365 {
00366 dc1394_dma_unlisten(itsHandle, &itsCam);
00367 dc1394_dma_release_camera(itsHandle, &itsCam);
00368 itsCameraOk = false;
00369 }
00370 if (itsHandle) { raw1394_destroy_handle(itsHandle); itsHandle = NULL; }
00371 #endif // HAVE_IEEE1394
00372 }
00373
00374
00375 IEEE1394grabber::~IEEE1394grabber()
00376 { }
00377
00378
00379 GenericFrameSpec IEEE1394grabber::peekFrameSpec()
00380 {
00381 GenericFrameSpec result;
00382
00383 result.nativeType = GenericFrame::VIDEO;
00384 result.videoFormat = itsGrabMode.getVal();
00385 result.videoByteSwap = itsByteSwap.getVal();
00386 result.dims = itsDims.getVal();
00387 result.floatFlags = 0;
00388
00389 return result;
00390 }
00391
00392
00393 SimTime IEEE1394grabber::getNaturalFrameTime() const
00394 {
00395 return SimTime::HERTZ(itsFPS.getVal());
00396 }
00397
00398
00399 void IEEE1394grabber::grabPrealloc(Image< PixRGB<byte> >& image,
00400 pthread_mutex_t *lock, int *count)
00401 {
00402 #ifndef HAVE_IEEE1394
00403 LFATAL("you must have ieee1394 (firewire) support and the libdc1394 "
00404 "library in order to use IEEE1394grabber");
00405 #else
00406 ASSERT(itsHandle); ASSERT(itsCameraOk);
00407 ASSERT(image.getWidth() == itsDims.getVal().w() &&
00408 image.getHeight() == itsDims.getVal().h());
00409 ASSERT(itsGrabMode.getVal() == VIDFMT_YUV444);
00410
00411
00412 while (dc1394_dma_single_capture(&itsCam) != DC1394_SUCCESS)
00413 {
00414 LINFO("Grab not ready...");
00415 usleep(IEEE1394WAIT);
00416 }
00417
00418
00419
00420 byte *data = (byte *)itsCam.dma_ring_buffer + itsCam.dma_frame_size *
00421 itsCam.dma_last_buffer;
00422 Image<PixRGB<byte> >::iterator aptr = image.beginw();
00423 Image<PixRGB<byte> >::iterator stop = image.endw();
00424
00425 if (lock) pthread_mutex_lock(lock);
00426 while(aptr != stop)
00427 {
00428
00429 (*aptr++) = PixRGB<byte>(PixVideoYUV<double>(data[1], data[0], data[2]));
00430 (*aptr++) = PixRGB<byte>(PixVideoYUV<double>(data[4], data[3], data[5]));
00431 data += 6;
00432 }
00433 if (count) *count += 1;
00434 if (lock) pthread_mutex_unlock(lock);
00435
00436
00437 if (dc1394_dma_done_with_buffer(&itsCam) != DC1394_SUCCESS)
00438 LERROR("Error releasing dma frame buffer");
00439 #endif // HAVE_IEEE1394
00440 }
00441
00442
00443 GenericFrame IEEE1394grabber::readFrame()
00444 {
00445 return GenericFrame(this->grabRaw());
00446 }
00447
00448
00449 VideoFrame IEEE1394grabber::grabRaw()
00450 {
00451 #ifndef HAVE_IEEE1394
00452 LFATAL("you must have ieee1394 (firewire) support and the libdc1394 "
00453 "library in order to use IEEE1394grabber");
00454 return VideoFrame();
00455 #else
00456 ASSERT(itsHandle); ASSERT(itsCameraOk);
00457
00458
00459 while (dc1394_dma_single_capture(&itsCam) != DC1394_SUCCESS)
00460 {
00461 LINFO("Grab not ready...");
00462 usleep(IEEE1394WAIT);
00463 }
00464
00465
00466 const byte* data = itsCam.dma_ring_buffer +
00467 itsCam.dma_frame_size * itsCam.dma_last_buffer;
00468
00469
00470 if (dc1394_dma_done_with_buffer(&itsCam) != DC1394_SUCCESS)
00471 LERROR("Error releasing dma frame buffer");
00472
00473 return VideoFrame(data, itsCam.dma_frame_size, itsDims.getVal(),
00474 itsGrabMode.getVal(), itsByteSwap.getVal(), false);
00475 #endif // HAVE_IEEE1394
00476 }
00477
00478
00479 void IEEE1394grabber::paramChanged(ModelParamBase* const param,
00480 const bool valueChanged,
00481 ParamClient::ChangeStatus* status)
00482 {
00483 #ifndef HAVE_IEEE1394
00484 LFATAL("you must have ieee1394 (firewire) support and the libdc1394 "
00485 "library in order to use IEEE1394grabber");
00486 #else
00487
00488 FrameIstream::paramChanged(param, valueChanged, status);
00489
00490
00491
00492
00493
00494
00495 #define HANDLE_PARAM(MODELPARAM, DC1394NAME) \
00496 if (itsHandle && valueChanged && param == &MODELPARAM) \
00497 { \
00498 LDEBUG("online change of " #DC1394NAME " from %s", \
00499 MODELPARAM.getName().c_str()); \
00500 if (dc1394_set_ ## DC1394NAME(itsHandle, itsCam.node, \
00501 MODELPARAM.getVal()) \
00502 != DC1394_SUCCESS) \
00503 { \
00504 *status = ParamClient::CHANGE_REJECTED; \
00505 LERROR("Unable to set " #DC1394NAME); \
00506 } \
00507 }
00508
00509 HANDLE_PARAM(itsBrightness, brightness);
00510 HANDLE_PARAM(itsExposure, exposure);
00511 HANDLE_PARAM(itsSharpness, sharpness);
00512 HANDLE_PARAM(itsHue, hue);
00513 HANDLE_PARAM(itsSaturation, saturation);
00514 HANDLE_PARAM(itsGamma, gamma);
00515 HANDLE_PARAM(itsShutter, shutter);
00516 HANDLE_PARAM(itsGain, gain);
00517
00518 #undef HANDLE_PARAM
00519
00520 if (itsHandle && valueChanged
00521 && (param == &itsWhiteBalBU || param == &itsWhiteBalRV))
00522 {
00523 LDEBUG("online change of white balance from %s",
00524 param->getName().c_str());
00525
00526 if (dc1394_set_white_balance(itsHandle, itsCam.node,
00527 itsWhiteBalBU.getVal(),
00528 itsWhiteBalRV.getVal())
00529 != DC1394_SUCCESS)
00530 {
00531 *status = ParamClient::CHANGE_REJECTED;
00532 LERROR("Unable to set white balance");
00533 }
00534 }
00535
00536 #endif // HAVE_IEEE1394
00537 }
00538
00539
00540
00541
00542
00543