OpenVideo Documentation

   Main Page       Modules       Class Hierarchy       Alphabetical List       Compound List       File List       Compound Members       Related Pages   

DSVLSrc.cxx

Go to the documentation of this file.
00001 /* ========================================================================
00002  * Copyright (C) 2005  Graz University of Technology
00003  *
00004  * This framework is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This framework is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this framework; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  * For further information please contact Denis Kalkofen under
00019  * <kalkofen@icg.tu-graz.ac.at> or write to Denis Kalkofen,
00020  * Graz University of Technology, Inffeldgasse 16a, A8010 Graz,
00021  * Austria.
00022  * ========================================================================
00023  * PROJECT: OpenVideo
00024  * ======================================================================== */
00033 #include <openvideo/nodes/DSVLSrc.h>
00034 #include <openvideo/openVideo.h>
00035 
00036 #ifdef ENABLE_DSVLSRC
00037 
00038 #include <DSVL.h>
00039 #include <openvideo/Manager.h>
00040 
00041 #ifdef OV_IS_WINXP
00042 #  ifdef OV_IS_DEBUG
00043 #    pragma message (">>> Linking against debug build of DSVL")
00044 #    pragma comment(lib,"DSVLd.lib")
00045 #  else 
00046 #    pragma message (">>> Linking against release build of DSVL")
00047 #    pragma comment(lib,"DSVL.lib")
00048 #  endif
00049 #else //WIN32
00050 
00051 #endif
00052 
00053 #include <openvideo/State.h>
00054 #include <assert.h>
00055 
00056 
00057 namespace openvideo {
00058 
00059 
00060 static const char*
00061 getDSVLPixelFormatString(PIXELFORMAT format)
00062 {
00063     switch(format)
00064     {
00065     default:
00066     case PIXELFORMAT_UNKNOWN:
00067         return "PIXELFORMAT_UNKNOWN";
00068     case PIXELFORMAT_UYVY:
00069         return "PIXELFORMAT_UYVY";
00070     case PIXELFORMAT_YUY2:
00071         return "PIXELFORMAT_YUY2";
00072     case PIXELFORMAT_RGB565:
00073         return "PIXELFORMAT_RGB565";
00074     case PIXELFORMAT_RGB555:
00075         return "PIXELFORMAT_RGB555";
00076     case PIXELFORMAT_RGB24:
00077         return "PIXELFORMAT_RGB24";
00078     case PIXELFORMAT_RGB32:
00079         return "PIXELFORMAT_RGB32";
00080     case PIXELFORMAT_INVALID:
00081         return "PIXELFORMAT_INVALID";
00082     case PIXELFORMAT_QUERY:
00083         return "PIXELFORMAT_QUERY";
00084     }
00085 }
00086 
00087 
00088 static void
00089 flipImage(unsigned char* nSrc, unsigned char *nDst, int nStride, int nHeight)
00090 {
00091     nSrc += nStride*(nHeight-1);
00092 
00093     for(int i=0; i<nHeight; i++)
00094     {
00095         memcpy(nDst, nSrc, nStride);
00096         nDst += nStride;
00097         nSrc -= nStride;
00098     }
00099 }
00100 
00101 
00102 
00103 // DSVLSrcFrame gives DSVLSrc full access to openvideo::Buffer
00104 class DSVLSrcBuffer : public Buffer
00105 {
00106 friend class DSVLSrc;
00107 public:
00108     DSVLSrcBuffer(DSVL_VideoSource* src, bool flipVert, State* state) : source(src), flipV(flipVert)
00109     {
00110         checkedOut = false;
00111         dsvlBuffer = copyBuffer = NULL;
00112         width = state->width;
00113         height = state->height;
00114         format = state->format;
00115     }
00116 
00117     ~DSVLSrcBuffer()
00118     {
00119         delete copyBuffer;
00120     }
00121 
00122     bool getNewFrame(unsigned int ctr)
00123     {
00124         DWORD wait_result = source->WaitForNextSample(100/60);
00125 
00126         if(wait_result!=0)          // time-out?
00127             return false;
00128 
00129         if(checkedOut)
00130         {
00131             // keeping DSVL buffsers is currently disabled
00132             // so this should never be called!
00133             assert(false);
00134             source->CheckinMemoryBuffer(mbHandle);
00135             checkedOut = false;
00136         }
00137 
00138         if(SUCCEEDED(source->CheckoutMemoryBuffer(&mbHandle, &dsvlBuffer)))
00139         {
00140             checkedOut = true;
00141 
00142             if(mbHandle.n <= sampleCtr)
00143             {
00144                 // only keep new frames
00145                 //
00146                 source->CheckinMemoryBuffer(mbHandle);
00147                 checkedOut = false;
00148                 return false;
00149             }
00150 
00151             sampleCtr = mbHandle.n;
00152 
00153             if(flipV)
00154             {
00155                 flipImage();
00156                 buffer = copyBuffer;
00157             }
00158             else
00159             {
00160                 copyImage();
00161                 buffer = copyBuffer;
00162                 //buffer = dsvlBuffer;
00163             }
00164 
00165             // FIXME-Daniel-20060530: currently there is a bug with keeping DSVL's memory buffers
00166             //                        so we always copy the video frames and release the buffer immediatelly
00167             source->CheckinMemoryBuffer(mbHandle);
00168             checkedOut = false;
00169 
00170             updateCtr = ctr;
00171             return true;
00172         }
00173 
00174         Manager::getInstance()->getLogger()->log("OpenVideo::DSVLSrc warning: failed to get video frame\n");
00175         return false;
00176     }
00177 
00178     void flipImage()
00179     {
00180         int bytesPerPixel = PixelFormat::getBitsPerPixel(format) / 8;       // assumes simple pixel-format (x times 8 bits)
00181         int stride = bytesPerPixel*width;
00182 
00183         if(copyBuffer==NULL)
00184             copyBuffer = new unsigned char[stride*height];
00185 
00186         openvideo::flipImage(dsvlBuffer, copyBuffer, stride, height);
00187     }
00188 
00189 
00190     void copyImage()
00191     {
00192         int bytesPerPixel = PixelFormat::getBitsPerPixel(format) / 8;       // assumes simple pixel-format (x times 8 bits)
00193         int stride = bytesPerPixel*width;
00194 
00195         if(copyBuffer==NULL)
00196             copyBuffer = new unsigned char[stride*height];
00197 
00198         memcpy(copyBuffer, dsvlBuffer, height*stride);
00199     }
00200 
00201 protected:
00202     DSVL_VideoSource    *source;
00203     MemoryBufferHandle  mbHandle;
00204     unsigned char       *dsvlBuffer, *copyBuffer;
00205     bool                flipV;
00206     bool                checkedOut;
00207     static unsigned int sampleCtr;
00208 };
00209 
00210 unsigned int DSVLSrcBuffer::sampleCtr = 0;
00211 
00212 
00213 // DSVLSrcState gives DSVLSrc full access to openvideo::State
00214 class DSVLSrcState : public State
00215 {
00216 public:
00217     ~DSVLSrcState()
00218     {
00219         for(size_t i=0; i<buffers.size(); i++)
00220             delete buffers[i];
00221         buffers.clear();
00222     }
00223 
00224     BufferVector& getBuffers()  {  return buffers;  }
00225 
00226     void setCurrentBuffer(Buffer* buf)  {  currentBuffer = buf;  }
00227 };
00228 
00229 #define DSVL_State(_STATE)  reinterpret_cast<DSVLSrcState*>(_STATE)
00230 
00231 
00232 DSVLSrc::DSVLSrc()
00233 {
00234     dsvlSource = NULL;
00235 
00236     name = typeName = "DSVLSrc";
00237     flipV = false;
00238     numBuffers = 2;
00239     updateCtr = 1;
00240 }
00241     
00242 DSVLSrc::~DSVLSrc()
00243 {
00244     state->unlockAllBuffers();
00245 
00246     // FIXME: is it sage to delete this here?
00247     delete state;
00248 
00249     delete dsvlSource;
00250     dsvlSource = NULL;
00251 }
00252 
00253 void 
00254 DSVLSrc::initPixelFormats()
00255 {
00256     pixelFormats.push_back(PIXEL_FORMAT(FORMAT_B8G8R8));
00257     pixelFormats.push_back(PIXEL_FORMAT(FORMAT_R5G6B5));
00258 }
00259 
00260 
00261 void
00262 DSVLSrc::init()
00263 {
00264     Manager::getInstance()->getLogger()->log("OpenVideo: start DSVLSrc\n");
00265 
00266     if(::CoInitialize(NULL) == S_FALSE)
00267     {
00268         Manager::getInstance()->getLogger()->log("OpenVideo: ERROR - CoInitialize() failed\n");
00269         return;
00270     }
00271 
00272     dsvlSource = new DSVL_VideoSource();
00273 
00274     LONG    cap_width = 0;
00275     LONG    cap_height = 0;
00276     double  cap_fps = 0.0;
00277     PIXELFORMAT pf = PIXELFORMAT_UNKNOWN;
00278 
00279     if(FAILED(dsvlSource->BuildGraphFromXMLFile(const_cast<char*>(configFileName.c_str()))))
00280     {
00281         Manager::getInstance()->getLogger()->log("OpenVideo: ERROR - DSVL failed reading config file\n");
00282         return;
00283     }
00284 
00285     if(FAILED(dsvlSource->GetCurrentMediaFormat(&cap_width,&cap_height,&cap_fps,&pf)))
00286     {
00287         Manager::getInstance()->getLogger()->log("OpenVideo: ERROR - DSVL failed retrieving video configuration\n");
00288         return;
00289     }
00290 
00291     if(curPixelFormat==FORMAT_B8G8R8 || curPixelFormat==FORMAT_R5G6B5)
00292     {
00293         if((curPixelFormat==FORMAT_B8G8R8 && pf!=PIXELFORMAT_RGB24) || (curPixelFormat==FORMAT_R5G6B5 && pf!=PIXELFORMAT_RGB565))
00294         {
00295             Manager::getInstance()->getLogger()->logEx("OpenVideo:DSVLSrc: wrong configuration - openvideo wants %s but DSVL delivers %s",
00296                                                        PixelFormat::FormatToString(curPixelFormat).c_str(), getDSVLPixelFormatString(pf));
00297             return;
00298         }
00299     }
00300     else
00301     {
00302         Manager::getInstance()->getLogger()->log("OpenVideo:DSVLSrc: ERROR - only B8G8R8 and R5G6B5 are supported\n");
00303         return;
00304     }
00305 
00306     if(FAILED(dsvlSource->EnableMemoryBuffer(1,numBuffers)))
00307     {
00308         Manager::getInstance()->getLogger()->log("OpenVideo: ERROR - DSVL setting memory buffers\n");
00309         return;
00310     }
00311 
00312     if(FAILED(dsvlSource->Run()))
00313     {
00314         Manager::getInstance()->getLogger()->log("OpenVideo: ERROR - DSVL failed to run\n");
00315         return;
00316     }
00317 
00318     Manager::getInstance()->getLogger()->logEx("OpenVideo: DSVL initialized with %d x %d at %d fps\n", cap_width, cap_height, (int)cap_fps);
00319 
00320     state = new DSVLSrcState();
00321     state->clear();
00322     state->width=cap_width;
00323     state->height=cap_height;
00324     state->format = curPixelFormat;
00325 
00326     for(int i=0; i<numBuffers; i++)
00327         DSVL_State(state)->getBuffers().push_back(new DSVLSrcBuffer(dsvlSource, flipV, state));
00328 }
00329 
00330 
00331 void
00332 DSVLSrc::preProcess()
00333 {
00334 }
00335 
00336 
00337 void
00338 DSVLSrc::process()
00339 {
00340     if(DSVLSrcBuffer* buffer = reinterpret_cast<DSVLSrcBuffer*>(state->findFreeBuffer()))
00341     {
00342         // our overloaded Buffer class does all the work...
00343         //
00344         if(buffer->getNewFrame(updateCtr))
00345         {
00346             DSVL_State(state)->setCurrentBuffer(buffer);
00347             updateCtr++;
00348 
00349             // Debug code to animate the video frame in case we don't get new video data
00350             // FIXME-Daniel-20060530: This should be removed in the future...
00351             static bool tst = false;
00352             static int c=0;
00353             if(tst)
00354             {
00355                 memset((void*)buffer->getPixels(), c, 320*240*3);
00356                 c = (c+1)&0xff;
00357             }
00358         }
00359     }
00360     else
00361         Manager::getInstance()->getLogger()->log("OpenVideo::DSVLSrc all frames locked, can not read a new camera image!\n");
00362 
00363 
00364     //FILE* fp = fopen("dump.raw", "wb");
00365     //fwrite(state->frame, 1, state->width*state->height*3, fp);
00366     //fclose(fp);
00367 }
00368 
00369 void
00370 DSVLSrc::postProcess()
00371 {
00372 }
00373 
00374 
00375 bool 
00376 DSVLSrc::setParameter(std::string key, std::string value)
00377 {
00378     if(Node::setParameter(key,value))
00379         return true;
00380 
00381     if(key=="config-file")
00382     {
00383         configFileName = value;
00384         return true;
00385     }
00386 
00387     if(key=="flip-v")
00388     {
00389         flipV = (value=="true" || value=="TRUE");
00390         return true;
00391     }
00392 
00393     if(key=="num-buffers")
00394     {
00395         numBuffers = atoi(value.c_str());
00396         if(numBuffers<1)
00397             numBuffers = 1;
00398         if(numBuffers>MAX_BUFFERS)
00399             numBuffers = MAX_BUFFERS;
00400         return true;
00401     }
00402 
00403     return false;
00404 }
00405 
00406 
00407 }  // namespace openvideo
00408 
00409 
00410 #endif //ENABLE_DSVLSRC
 This page was generated at Wed May 31 13:04:16 2006 for OpenVideo by Doxygen.
 If you have any comments, please send a message to schmalstieg@icg.tu-graz.ac.at.
www.studierstube.org