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 <cstddef>
00039 #include <string>
00040
00041 #include "Component/OptionManager.H"
00042 #include "Devices/DeviceOpts.H"
00043 #include "Image/Image.H"
00044 #include "Image/Pixels.H"
00045 #include "Image/MathOps.H"
00046 #include "Raster/GenericFrame.H"
00047 #include "Raster/Raster.H"
00048 #include "Util/Assert.H"
00049 #include "Util/SimTime.H"
00050 #include "Util/sformat.H"
00051 #include "Video/VideoFrame.H"
00052
00053 #include "Devices/XCgrabberFlex.H"
00054
00055
00056 #define XCWAIT 50
00057
00058 #define UNITMAP 1
00059 #define USEDBUFFER 16
00060
00061
00062 XCgrabberFlex::XCgrabberFlex(OptionManager& mgr,
00063 const std::string& descrName,
00064 const std::string& tagName,
00065 const ParamFlag flags) :
00066 FrameIstream(mgr, descrName, tagName),
00067 itsDims(&OPT_FrameGrabberDims, this, Dims(1920, 1080), USE_MY_VAL),
00068 itsGrabMode(&OPT_FrameGrabberMode, this, VIDFMT_BAYER_GB, USE_MY_VAL),
00069 itsByteSwap(&OPT_FrameGrabberByteSwap, this, false, USE_MY_VAL),
00070 itsWhiteBalTarR(&OPT_FrameGrabberWhiteBalTargetR, this, false, USE_MY_VAL),
00071 itsWhiteBalTarG(&OPT_FrameGrabberWhiteBalTargetG, this, false, USE_MY_VAL),
00072 itsWhiteBalTarB(&OPT_FrameGrabberWhiteBalTargetB, this, false, USE_MY_VAL),
00073 itsWhiteBalRefR(&OPT_FrameGrabberWhiteBalReferenceR, this, false, USE_MY_VAL),
00074 itsWhiteBalRefG(&OPT_FrameGrabberWhiteBalReferenceG, this, false, USE_MY_VAL),
00075 itsWhiteBalRefB(&OPT_FrameGrabberWhiteBalReferenceB, this, false, USE_MY_VAL),
00076 itsGamma(&OPT_XCFrameGrabberGamma, this, 1.0, USE_MY_VAL | ALLOW_ONLINE_CHANGES),
00077 itsFPS(&OPT_FrameGrabberFPS, this, 30.0, USE_MY_VAL)
00078 #ifdef HAVE_XCLIB
00079 ,itsFormatFile(&OPT_XCFormatFileName, this),
00080 itsCameraOk(false),
00081 itsImgBuf(NULL)
00082 #endif
00083 {
00084 #ifdef HAVE_XCLIB
00085 memset(&itsXclib, 0, sizeof(itsXclib));
00086 itsXclib.ddch.len = sizeof(itsXclib);
00087 itsXclib.ddch.mos = XCMOS_LIBS;
00088
00089 itsStatep = NULL;
00090 itsLastBuf = 0;
00091 #endif
00092 }
00093
00094
00095 void XCgrabberFlex::start1()
00096 {
00097 #ifndef HAVE_XCLIB
00098 LFATAL("you must have XC support and the xclib library in order to use XCgrabberFlex");
00099 #else
00100
00101 int i;
00102 if(!strcmp(itsFormatFile.getVal().c_str(),"noFile"))
00103 {
00104 LINFO("use default setup configure format");
00105 char* format =(char*)("default");
00106 i = xclib::xclib_open(&itsXclib, NULL,NULL, format, NULL);
00107 }
00108 else
00109 {
00110 LINFO("use input format file as configure file");
00111 char* formatFile = (char*)(itsFormatFile.getVal().c_str());
00112 i = xclib::xclib_open(&itsXclib, NULL, NULL, NULL, formatFile);
00113 }
00114 if(i != 0)
00115 {
00116 LINFO("error code %d\n", i);
00117 LFATAL("can not open the XC camera");
00118 }
00119
00120 switch(itsGrabMode.getVal())
00121 {
00122 case VIDFMT_BAYER_GB12: itsBitDepth = 12; break;
00123 case VIDFMT_BAYER_GR12: itsBitDepth = 12; break;
00124 case VIDFMT_BAYER_RG12: itsBitDepth = 12; break;
00125 case VIDFMT_BAYER_BG12: itsBitDepth = 12; break;
00126 case VIDFMT_BAYER_GB: itsBitDepth = 8; break;
00127 case VIDFMT_BAYER_GR: itsBitDepth = 8; break;
00128 case VIDFMT_BAYER_RG: itsBitDepth = 8; break;
00129 case VIDFMT_BAYER_BG: itsBitDepth = 8; break;
00130 default: LFATAL("ERROR in specify the xc grab mode");
00131 }
00132
00133
00134 struct xclib::pxdevinfo pxinfo;
00135 memset(&pxinfo, 0, sizeof(pxinfo));
00136 pxinfo.ddch.len = sizeof(pxinfo);
00137 pxinfo.ddch.mos = PXMOS_DEVINFO;
00138
00139 itsXclib.pxdev.getDevInfo(&(itsXclib.pxdev), UNITMAP, 0, &pxinfo);
00140 LINFO("find %d baords, frame buffer memory = %.4f Kbytes",
00141 pxinfo.nunits,(double)pxinfo.memsize/1024);
00142
00143
00144 WhiteBalance();
00145
00146 struct xclib::pxlibservice pxlib = itsXclib.pxlib;
00147 struct xclib::xcdevservice xcdev = itsXclib.xcdev;
00148
00149
00150 i = pxlib.allocStateCopy(&pxlib, 0, 0, &itsStatep);
00151 LINFO("allocate state copy (video state), result code: %d", i);
00152
00153 i = pxlib.initStateCopy(&pxlib, 0, 0,
00154 itsStatep, &pxinfo, (char*)("default"), PXMODE_DIGI);
00155 LINFO("init state copy (video state), result code: %d",i);
00156 pxlib.defineState(&pxlib, 0, itsStateid, itsStatep);
00157
00158
00159
00160
00161 LINFO("pxvidimage dims = %d,%d\n",itsStatep->vidres->x.vidoffset,
00162 itsStatep->vidres->x.vidoffsend);
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 i = xcdev.setVideoConfig(&xcdev,UNITMAP, 0, 0, itsStatep, NULL);
00224 LINFO("set video configure code %d", i);
00225
00226
00227 i = xcdev.setLiveSeqBuf
00228 (&xcdev, UNITMAP, 0, 0, itsStatep, NULL, 1, USEDBUFFER, 1, 0, 1, 0);
00229 if(i != 0)
00230 {
00231 LINFO("start capture error code %d", i);
00232 LFATAL("the imaging board can not work on live mode\n");
00233 }
00234
00235
00236
00237 xclib::pxbuffer_t bufferID =
00238 (xclib::pxbuffer_t)xcdev.getLiveStatus(&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00239 if(bufferID ==0) LINFO("Grab not ready...");
00240
00241 while( bufferID == 0 )
00242 { usleep(XCWAIT);
00243 bufferID = (xclib::pxbuffer_t)xcdev.getLiveStatus
00244 (&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00245 }
00246
00247 const unsigned int bufSz = itsDims.getVal().sz() * (int)ceil(itsBitDepth/8);
00248 itsImgBuf = (byte*)malloc(bufSz);
00249
00250 itsCameraOk = true;
00251
00252 #endif // HAVE_XCLIB
00253 }
00254
00255
00256 void XCgrabberFlex::stop2()
00257 {
00258 #ifndef HAVE_XCLIB
00259
00260 LERROR("you must have XC support and the xclib library in order to use XCgrabberFlex");
00261 #else
00262 if (itsCameraOk)
00263 {
00264 xclib_close(&itsXclib);
00265 itsCameraOk = false;
00266 }
00267 #endif // HAVE_XCLIB
00268 }
00269
00270
00271 XCgrabberFlex::~XCgrabberFlex()
00272 {
00273 #ifdef HAVE_XCLIB
00274 free(itsImgBuf);
00275 #endif
00276 }
00277
00278
00279 void XCgrabberFlex::WhiteBalance()
00280 {
00281 #ifdef HAVE_XCLIB
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 #endif
00327 }
00328
00329
00330 GenericFrameSpec XCgrabberFlex::peekFrameSpec()
00331 {
00332 GenericFrameSpec result;
00333
00334 result.nativeType = GenericFrame::VIDEO;
00335 result.videoFormat = itsGrabMode.getVal();
00336 result.videoByteSwap = itsByteSwap.getVal();
00337 result.dims = itsDims.getVal();
00338 result.floatFlags = 0;
00339
00340 return result;
00341 }
00342
00343
00344 SimTime XCgrabberFlex::getNaturalFrameTime() const
00345 {
00346 return SimTime::HERTZ(itsFPS.getVal());
00347 }
00348
00349
00350
00351
00352 GenericFrame XCgrabberFlex::readFrame()
00353 {
00354 return GenericFrame(this->grabRaw());
00355 }
00356
00357
00358 VideoFrame XCgrabberFlex::grabRaw()
00359 {
00360 #ifndef HAVE_XCLIB
00361 LFATAL("you must have XC support and the xclib library in order to use XCgrabberFlex");
00362 return VideoFrame();
00363 #else
00364 ASSERT(itsCameraOk);
00365 int i = 0;
00366
00367 struct xclib::xcdevservice xcdev = itsXclib.xcdev;
00368 struct xclib::pxlibservice pxlib = itsXclib.pxlib;
00369
00370
00371 xclib::pxbuffer_t bufferID = (xclib::pxbuffer_t)xcdev.getLiveStatus
00372 (&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00373
00374 while( bufferID == itsLastBuf)
00375 {
00376 bufferID = (xclib::pxbuffer_t)xcdev.getLiveStatus
00377 (&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00378 usleep(100);
00379 }
00380 if(itsLastBuf != 0 && bufferID != (itsLastBuf)%USEDBUFFER + 1)
00381 {
00382 LINFO("last buf id= %4d, curr buf id= %4d",(int)itsLastBuf,(int)bufferID);
00383 LERROR("buffer error: buffer mis order");
00384 }
00385
00386 pthread_mutex_lock(&qmutex_buf);
00387 itsLastBuf = bufferID;
00388 pthread_mutex_unlock(&qmutex_buf);
00389
00390
00391 int dataMode = (itsBitDepth == 8 ? PXDATUINT8:PXDATUINT16);
00392
00393 const unsigned int bufSz = itsDims.getVal().sz() * (int)ceil(itsBitDepth/8);
00394 const unsigned int imgSz = itsDims.getVal().sz();
00395
00396
00397 struct xclib::pximage pximg;
00398
00399 i = pxlib.initPximage(&pxlib, UNITMAP,
00400 &pximg, 1, PXHINTBAYER, 0, itsStateid, bufferID, 0);
00401
00402 pximg.wind.nw.x = 1920/2 - itsDims.getVal().w()/2;
00403 pximg.wind.nw.y = 1080/2 - itsDims.getVal().h()/2;
00404 pximg.wind.se.x = 1920/2 + itsDims.getVal().w()/2;
00405 pximg.wind.se.y = 1080/2 + itsDims.getVal().h()/2;
00406
00407 LINFO("pximgsize %d,%d", pximg.wind.nw.x,pximg.wind.se.x);
00408
00409 if (i<1)
00410 LFATAL("error, can not define a pximage, code: %d",i);
00411
00412
00413 if(pximg.ioset(&pximg, PXRXSCAN | PXIWRAP, dataMode, 0x01) < 0)
00414 {
00415 LFATAL("error in ioset, can not set frame buffer read");
00416 return VideoFrame();
00417 }
00418
00419 if(imgSz != pximg.ioread(&pximg, PXRXSCAN | PXIWRAP, itsImgBuf,bufSz,0,0))
00420 {
00421 LFATAL("error in reading frame buffer(size error),"
00422 "expected size = %d", imgSz);
00423 return VideoFrame();
00424 }
00425 return VideoFrame(itsImgBuf, bufSz, itsDims.getVal(),
00426 itsGrabMode.getVal(), itsByteSwap.getVal(), false);
00427
00428 #endif // HAVE_XCLIB
00429 }
00430
00431
00432 void XCgrabberFlex::paramChanged(ModelParamBase* const param,
00433 const bool valueChanged,
00434 ParamClient::ChangeStatus* status)
00435 {
00436 #ifndef HAVE_XCLIB
00437 LFATAL("you must have XC support and the xclib library in order to use XCgrabberFlex");
00438 #else
00439 FrameIstream::paramChanged(param, valueChanged, status);
00440 #endif // HAVE_XCLIB
00441 }
00442
00443
00444 #ifdef HAVE_XCLIB
00445 xclib::pxbuffer_t XCgrabberFlex::getCurrBufID()
00446 {
00447 xclib::pxbuffer_t tmp;
00448 pthread_mutex_lock(&qmutex_buf);
00449 tmp = itsLastBuf;
00450 pthread_mutex_unlock(&qmutex_buf);
00451 return tmp;
00452 }
00453 #endif
00454
00455
00456
00457
00458
00459
00460