00001 /*!@file Devices/IEEE1394grabber.C Interface with a FireWire digital camera */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/IEEE1394grabber.C $ 00035 // $Id: IEEE1394grabber.C 10345 2008-10-15 17:27:10Z icore $ 00036 // 00037 00038 #include "Devices/IEEE1394grabber.H" 00039 00040 #include "Component/OptionManager.H" // for option alias requests 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 // wait when polling for a frame (in us): 00056 #define IEEE1394WAIT 1 00057 00058 // This code is somewhat inspired from the grab_gray_image.c example 00059 // code provided with the libdc1394 distribution by Gord Peters, and 00060 // from the Coriander source code. 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 // Figure out which of the IEEE1394 grab modes to use. We don't 00077 // support the various IEEE1394 MONO16 modes. 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 // Figure out which framerate to use 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 /* can't happen */ 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 // NOTE that contrary to the common case, we may give (by default 00173 // value of the 'flags' param) USE_MY_VAL here when we construct the 00174 // OModelParam objects; that means that we push our values into the 00175 // ModelManager as the new default values, rather than having our 00176 // param take its value from the ModelManager's default 00177 itsDevName(&OPT_FrameGrabberDevice, this, "/dev/video1394/0", flags), // device 00178 itsChannel(&OPT_FrameGrabberChannel, this, 0, flags), // first firewire card 00179 itsSubChan(&OPT_FrameGrabberSubChan, this, 0, flags), 00180 itsDims(&OPT_FrameGrabberDims, this, Dims(320, 240), flags), 00181 itsGrabMode(&OPT_FrameGrabberMode, this, VIDFMT_YUV422, flags), // grab mode 00182 itsByteSwap(&OPT_FrameGrabberByteSwap, this, false, flags), // no byte-swapping 00183 itsFPS(&OPT_FrameGrabberFPS, this, 30.0, flags), 00184 itsNbuf(&OPT_FrameGrabberNbuf, this, 4, flags), // number of grab buffers 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 // request a bunch of camera aliases which work with IEEE1394: 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 // create raw1394 handle: 00217 itsHandle = dc1394_create_handle(itsChannel.getVal()); 00218 if (itsHandle == 0) LFATAL("Cannot create raw1394 handle"); 00219 00220 // list camera nodes available on bus: 00221 int nb = raw1394_get_nodecount(itsHandle); 00222 LDEBUG("Found %d nodes on port %d", nb, itsChannel.getVal()); 00223 int nc; // parameter 1 below is to provide terminal debug info 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 // check if camera is the highest node (see iso transfer bug): 00233 if (node[subchan] == nb - 1) 00234 LFATAL("You need to insmod ohci1394 attempt_root=1"); 00235 00236 #ifdef IEEE1394NEW 00237 // newer versions have an extra arg do_extra_buffering (here set to 0): 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 // old syntax: 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 // set features based on ModelParam values 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 // report camera features: 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 // report additional features such as supported modes: 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 // start data transfers: 00319 if (dc1394_start_iso_transmission(itsHandle, itsCam.node) != DC1394_SUCCESS) 00320 LFATAL("Cannot start data transmission"); 00321 00322 // just double-checking that all settings are correct: 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 // don't LFATAL() in stop() since it may be called in a destructor chain 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 // capture next frame: 00412 while (dc1394_dma_single_capture(&itsCam) != DC1394_SUCCESS) 00413 { 00414 LINFO("Grab not ready..."); 00415 usleep(IEEE1394WAIT); 00416 } 00417 00418 // Convert grabbed buffer to RGB (code same as in fromVideoYUV444() 00419 // of Image_ColorOps.H): 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 // data stored as: u0, y0, v0, u1, y1, v1 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 // free that buffer: 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 /* can't happen */ return VideoFrame(); 00455 #else 00456 ASSERT(itsHandle); ASSERT(itsCameraOk); 00457 00458 // capture next frame: 00459 while (dc1394_dma_single_capture(&itsCam) != DC1394_SUCCESS) 00460 { 00461 LINFO("Grab not ready..."); 00462 usleep(IEEE1394WAIT); 00463 } 00464 00465 // get the buffer: 00466 const byte* data = itsCam.dma_ring_buffer + 00467 itsCam.dma_frame_size * itsCam.dma_last_buffer; 00468 00469 // free that buffer: 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 // just handle online changes here (i.e. changes that come while we 00491 // are already started); if the change happens before start() then 00492 // we will pick up the proper dc1394 settings in start() so we don't 00493 // need to handle the change here 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 /* So things look consistent in everyone's emacs... */ 00541 /* Local Variables: */ 00542 /* indent-tabs-mode: nil */ 00543 /* End: */