OpenVideo Documentation

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

Manager.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  * ======================================================================== */
00032 #include <openvideo/Manager.h>
00033 #include <ace/Thread.h>
00034 #include <ace/Condition_Thread_Mutex.h>
00035 #include <ace/Thread_Mutex.h>
00036 
00037 // The configOV.h file is only used on windows. On linux command line
00038 // arguments are used instead.
00039 #ifdef HAVE_CONFIGOV_H
00040 #include <openvideo/configOV.h>
00041 #endif
00042 
00043 #include <tinyxml/tinyxml.h>
00044 
00045 #include <openvideo/NodeFactory.h>
00046 #include <openvideo/Node.h>
00047 
00048 #include <GL/gl.h>
00049     
00050 using namespace openvideo;
00051 
00053 #ifdef ENABLE_GLUTSINK
00054 #include <openvideo/nodes/GLUTSinkFactory.h>
00055 #endif
00056 
00057 #ifdef ENABLE_TESTSRC
00058 #include <openvideo/nodes/TestSrcFactory.h>
00059 #endif
00060 
00061 #ifdef ENABLE_GL_TEXTURE_2D_SINK
00062 #include <openvideo/nodes/GL_TEXTURE_2D_SinkFactory.h>
00063 #endif
00064 
00065 #ifdef ENABLE_VIDEOWRAPPERSRC
00066 #include <openvideo/nodes/VideoWrapperSrcFactory.h>
00067 #endif
00068 
00069 #ifdef ENABLE_DSVLSRC
00070 #include <openvideo/nodes/DSVLSrcFactory.h>
00071 #endif
00072 
00073 #ifdef ENABLE_V4LSRC
00074 #include <openvideo/nodes/V4LSrcFactory.h>
00075 #endif
00076 
00077 #ifdef ENABLE_V4L2SRC
00078 #include <openvideo/nodes/V4L2SrcFactory.h>
00079 #endif
00080 
00081 #ifdef ENABLE_VIDEOSINK
00082 #include <openvideo/nodes/VideoSinkFactory.h>
00083 #endif
00084 
00085 #ifdef ENABLE_SPECTECSRC
00086 #include <openvideo/nodes/SpectecSrcFactory.h>
00087 #endif
00088 
00089 #ifdef ENABLE_IMAGESRC
00090 #include <openvideo/nodes/ImageSrcFactory.h>
00091 #endif
00092 
00093 #ifdef ENABLE_OPENCV
00094 #include <openvideo/nodes/OpenCVSrcFactory.h>
00095 #endif
00096 
00097 #include <iostream>
00098 
00099 void (*Manager::traversalFunc)    (void*)=NULL;
00100 void (*Manager::initTraversalFunc)(void*)=NULL;
00101 void* Manager::traversalData=NULL;
00102 void* Manager::initTraversalData=NULL;
00103 bool  Manager::travBlock=false;
00104 bool  Manager::hasGLContext=false;
00105 Manager* Manager::instance=NULL;
00106 bool Manager::isUserInterfaceRunning=false;
00107 
00108 Manager::Manager()
00109 {
00110   logger=  new  Logger();
00111   scheduler=new Scheduler();
00112   initNodeFactories();
00113     
00114   setInitTravFunction(&Manager::initTopologicalSortedTraversal,&(nodes));
00115   setTravFunction(&Manager::topologicalSortedTraversal,&(nodes));
00116   isRunning=true;
00117   updating=false;
00118   hasParsed=false;
00119   updateLock=new ACE_Thread_Mutex();
00120   updateLockCondition=new ACE_Condition_Thread_Mutex(*updateLock);
00121   idleSetGLContext=false;
00122   idleDeleteGLContext=false;
00123   //dc=NULL;
00124   glContext=NULL;
00125   glContextChanged=false;
00126 #ifdef LINUX
00127   dsp=NULL;
00128 #endif
00129 }
00130 
00131 // Destructor method.
00132 Manager::~Manager()
00133 {
00134   //clean up graph
00135   for(int i=(int)(nodes.size())-1;i>=0;i--)
00136     {
00137       //visit node i
00138       delete nodes.at(i);
00139     }
00140   nodes.clear();
00141   delete logger;
00142   delete scheduler;
00143 }
00144 
00145 void 
00146 Manager::update(void*)
00147 {
00148    Manager* self=Manager::getInstance();
00149    self->updateLock->acquire();
00150    if(self->isRunning)
00151    {
00152        self->updating=true;
00153        (*Manager::traversalFunc)(Manager::traversalData);
00154        self->updating=false;
00155    }
00156    else
00157    {
00158        self->doIdleTasks();
00159    }
00160    self->updateLockCondition->broadcast();
00161    self->updateLock->release();
00162 }
00163 
00164 void 
00165 Manager::doIdleTasks()
00166 {
00168     if(idleSetGLContext)
00169     {
00170         idleSetGLContext=false;
00171         if(dc && glContext)
00172         {
00173             
00174 #ifdef WIN32
00175           hasGLContext=wglMakeCurrent(dc,glContext);
00176 #endif
00177 #ifdef LINUX
00178           hasGLContext=glXMakeCurrent(dsp,dc,glContext);
00179 #endif
00180             if(!hasGLContext)
00181                 logger->logEx("OpenVideo: couldn't set glContext\n");
00182             else
00183                 logger->logEx("OpenVideo: successfully set glContext\n") ;
00184         }
00185     }
00187     else if(idleDeleteGLContext)
00188     {
00189       
00190         idleDeleteGLContext=false;   
00191 
00192 #ifdef OV_IS_WINDOWS
00193         hasGLContext=(!wglDeleteContext(glContext));
00194 #endif
00195 #ifdef LINUX
00196     glXDestroyContext(dsp, glContext);
00197 #endif
00198         if(hasGLContext)
00199             logger->logEx("OpenVideo: couldn't delete glContext\n");
00200         else
00201         {
00202             logger->logEx("OpenVideo: successfully deleted glContext\n") ;
00203             //try to set a new glcontext
00204             glContextChanged=true;
00205         }
00206            
00207         
00208     }
00209 
00210 
00211     resume();
00212 }
00213 
00214 
00215 void 
00216 Manager::pause()
00217 {
00218     updateLock->acquire();
00219     if(isRunning)
00220     {
00221         isRunning =false;
00222         updateLockCondition->wait();      
00223     }
00224     
00225     updateLock->release();
00226 }
00227 
00228 #ifdef WIN32
00229     void 
00230     Manager::setGLContext(HGLRC _glContext,HDC _dc)
00231     {
00232         printf("    Manager::setGLContext(HGLRC _glContext,HDC _dc) \n");
00233         glContext=_glContext;
00234         dc=_dc;
00235         idleSetGLContext=true;
00236         pause();
00237     }
00238 #endif
00239 
00240 #ifdef LINUX
00241     void 
00242     Manager::setGLContext(GLXDrawable _drawable, GLXContext _ovGLContext, Display* _dsp)
00243     {
00244         dc=_drawable;
00245         glContext=_ovGLContext;
00246         dsp=_dsp;
00247         pause();
00248     }
00249 
00250 #endif
00251 
00252 void
00253 Manager::deleteGLContext()
00254 {
00255     idleDeleteGLContext=true;
00256     pause();
00257 }
00258 void 
00259 Manager::resume()
00260 {
00261     updateLock->acquire();
00262     isRunning=true;
00263     updateLock->release();
00264 }
00265 
00266 bool
00267 Manager::isStarted()
00268 {
00269   return isRunning;
00270 }
00271 
00272 Manager* 
00273 Manager::getInstance()
00274 {
00275   if(!Manager::instance)
00276     Manager::instance=new Manager();
00277 
00278   return Manager::instance;
00279         
00280 
00281 }
00282 
00283 void
00284 Manager::buildSubGraph(TiXmlElement * parentElement, Node* parentNode)
00285 {
00286   TiXmlElement * element = parentElement->FirstChildElement();
00287   while(element)
00288     {
00289       Node* curNode=addNode(element);
00290 
00291       parentNode->addOutput(curNode);
00292       curNode->addInput(parentNode);
00293 
00294       buildSubGraph(element,curNode);
00295       element = element->NextSiblingElement();
00296     }
00297 }
00298 
00299 Node* 
00300 Manager::addNode(TiXmlElement *element)
00301 {
00302   //search for attribute "use"
00303 
00304   TiXmlAttribute* attribute = element->FirstAttribute();
00305   bool isUse=false;
00306   std::string useName="";
00307   while(attribute)
00308     {
00309       if(!strcmp(attribute->Name(),"USE"))
00310         {
00311           //node is just referenced 
00312           isUse=true;
00313           useName=attribute->Value();
00314           break;
00315         }
00316       attribute = attribute->Next();
00317     }
00318     
00319   Node* curNode=NULL;
00320   if(isUse){
00321     //get node from defNodes
00322     std::vector<Node*>::iterator it;
00323     for(it=defNodes.begin();it!=defNodes.end();it++){
00324       Node* defNode=(*it);
00325       if(!strcmp(defNode->getDefName(),useName.c_str()))
00326         {
00327           curNode=defNode;
00328           break;
00329         }
00330     }
00331   }
00332   else{
00333     //find factory
00334     NodeFactory *nodeFactory=NULL;
00335     for(int i=0;i<(int)(factories.size());i++)
00336       {
00337         if(!strcmp(factories[i]->getNodeTypeId(),element->Value())){
00338           nodeFactory=factories[i];
00339           break;
00340         }
00341       }
00342     if(!nodeFactory){
00343       logger->logEx("OpenVideo: can't find a factory for %s\n",element->Value());
00344       exit(-1);
00345     }
00346     //create Node 
00347         
00348     curNode=nodeFactory->createNode();
00349     nodes.push_back(curNode);
00350   }//if(isUse)..else
00351         
00352   //get attributesj
00353   attribute = element->FirstAttribute();
00354   while(attribute)
00355     {
00356       if(!strcmp(attribute->Name(),"DEF")){
00357         defNodes.push_back(curNode);
00358       }
00359         
00360       curNode->setParameter(attribute->Name(), attribute->Value());
00361       attribute = attribute->Next();
00362     }
00363 
00364   return curNode;
00365 }
00366 
00367 void
00368 Manager::parseConfiguration(TiXmlElement* element)
00369 {
00370   scheduler->parseConfiguration(element);
00371 }
00372 
00373 // parse the xml file and build the graph.
00374 bool
00375 Manager::parseConfiguration(const std::string& filename)
00376 {   
00377     if (hasParsed)
00378         return false;
00379   TiXmlDocument* document = new TiXmlDocument();
00380 
00381   if(!document->LoadFile(filename.c_str()))
00382     {
00383       logger->logEx("OpenVideo:An error occured during parsing\n   Message: %s\n", document->ErrorDesc());
00384       return false;
00385     }
00386   //
00387   TiXmlElement* root = document->RootElement();
00388   parseConfiguration(root);
00389   TiXmlElement* element = root->FirstChildElement();
00390   while(element)
00391     {
00392       Node* curNode=addNode(element);
00393       buildSubGraph(element,curNode);
00394       element = element->NextSiblingElement();
00395     }
00396   //
00398   document->Clear();
00399   delete document;
00400 
00401   hasParsed=true;
00402   return true;
00403 }
00404 
00405 void 
00406 Manager::setTravFunction(void (*travFunction)(void*),void *data)
00407 {
00408   Manager::traversalFunc=travFunction;
00409   Manager::traversalData=data;
00410 }
00411 
00412 void 
00413 Manager::setInitTravFunction(void (*initTravFunction)(void*),void* data)
00414 {   
00415   Manager::initTraversalFunc=initTravFunction;
00416   Manager::initTraversalData=data;
00417 }
00418 
00419 void 
00420 Manager::run()
00421 {
00422   
00423   scheduler->init();
00424   //start control  thread
00425   ACE_hthread_t* controlThreadHandle = new ACE_hthread_t();
00426   if(ACE_Thread::spawn((ACE_THR_FUNC)Manager::startUserInterface,
00427       0,    
00428      THR_NEW_LWP|THR_JOINABLE,  
00429       0,    
00430      controlThreadHandle,
00431       0,    
00432       0,    
00433      0
00434      )==-1)
00435   { 
00436       printf("Error in spawning thread\n"); 
00437   }
00438   scheduler->run();
00439    
00440 }
00441 
00442 void* 
00443 Manager::startUserInterface(void *)
00444 { 
00445     std::string inputLine;
00446     Manager::isUserInterfaceRunning=true;
00447     while(Manager::isUserInterfaceRunning)
00448     {
00449         printf("openvideo>");
00450         getline(std::cin, inputLine );
00452         // get token 
00453         std::vector<std::string> inputArr;
00454         bool newToken=true;
00455         std::string curChar ;
00456         for(int i=0;i<(int)inputLine.size();i++)
00457         {
00458             curChar=inputLine[i];
00459             if(curChar==" "){
00460                 newToken=true;
00461                 continue;
00462             }
00463             if(newToken){
00464                 std::string token="";
00465                 while(curChar!=" " && i<(int)inputLine.size()) 
00466                 {
00467                     token.push_back(curChar[0]);
00468                     i++;
00469                     curChar=inputLine[i];
00470                 }
00471                 i--;
00472                 inputArr.push_back(token);
00473                 newToken=false;
00474             }
00475         }
00476         //process token
00477         if(inputArr.size()>0)
00478         {
00479             std::string command;
00480             command=inputArr[0];
00481             if(command=="load"){
00482 
00483             }
00484             else if(command=="exit"){
00485                 Manager::isUserInterfaceRunning=false;
00486                 Manager::getInstance()->stop();
00487             }
00488             else{
00489                 printf("ERROR:: dont understand -%s-\n",command.c_str());
00490             }
00491         }
00492     }
00493 
00494     return 0;
00495 }
00496 
00497 void 
00498 Manager::stop()
00499 {
00500     scheduler->stop();
00501     
00502     for(int i=(int)nodes.size()-1;  i>=0; i--) {
00503     logger->logEx("Closing node %s\n",nodes[i]->getName());
00504     nodes[i]->stop();
00505     }
00506 }
00507 
00508 
00509 void 
00510 Manager::initTraversal()
00511 {
00512   //validate pixel format
00513   for(int i=0;i<(int)nodes.size();i++)
00514     {
00515       nodes[i]->initPixelFormats();
00516       if(!nodes[i]->validateCurrentPixelFormat())
00517         {
00518           logger->logEx("OV: %s uses an unknown pixel format\n",nodes[i]->getName());
00519           exit(-1);
00520         }
00521     }
00522   (*Manager::initTraversalFunc)(initTraversalData);
00523 }
00524 
00525 void 
00526 Manager::initTopologicalSortedTraversal(void* nodeList)
00527 {
00528   std::vector<Node *>* nodes=(std::vector<Node *>*)nodeList;
00529   std::vector<Node *> sortedNodes;
00530   //sort nodes
00531   int i;
00532   while((int)nodes->size()>0)
00533     {
00534       //find node with in degree==0
00535       for (i=0;i<(int)nodes->size();i++){
00536         if(nodes->at(i)->getCurInDegree()==0)
00537           {
00538             std::vector<Node*> *outputs=nodes->at(i)->getOutputs();
00539             std::vector<Node*>::iterator it;
00540             for(it=outputs->begin();it!=outputs->end();it++){
00541               Node* outNode=(*it);
00542               outNode->decCurInDegree();
00543             }
00544         
00545             sortedNodes.push_back(nodes->at(i));
00546             nodes->erase(nodes->begin()+i);
00547             break;
00548           }
00549       }
00550     }
00551   //write back to nodeList
00552   for (i=0;i<(int)sortedNodes.size();i++)
00553     {
00554       nodes->push_back(sortedNodes.at(i));
00555     }
00556   //init all nodes
00557   for(i=0;i<(int)nodes->size();i++)
00558     {
00559       nodes->at(i)->init();
00560     }
00561   //start all nodes
00562   for(i=0;i<(int)nodes->size();i++)
00563     {
00564       nodes->at(i)->start();
00565     }
00566 }
00567 
00568 void 
00569 Manager::topologicalSortedTraversal(void* nodeList)
00570 {
00571   if(!travBlock){
00572     travBlock=true;
00573     std::vector<Node *>* nodes=(std::vector<Node *>*)nodeList;
00574 
00575     // preprocess graph
00576     for(int i=0;i<(int)nodes->size();i++){
00577         //visit node i
00578         nodes->at(i)->preProcess();
00579     }
00580     // process graph
00581     for(int i=0;i<(int)nodes->size();i++){
00582       //visit node i
00583       nodes->at(i)->process();
00584     }
00585     // post process 
00586     for(int i=0;i<(int)nodes->size();i++){
00587       //visit node i
00588       nodes->at(i)->postProcess();
00589     }
00590     travBlock=false;
00591   }
00592 }
00593 
00594 void 
00595 Manager::addNodeFactory(NodeFactory *aFactory)
00596 {
00597   factories.push_back(aFactory);    
00598 }
00599 
00600 
00601 
00602 Node* 
00603 Manager::getNode(std::string nodeName)
00604 {
00605   for (int i=0;i<(int)nodes.size();i++){
00606     if(!strcmp(nodes[i]->getName(),nodeName.c_str()))
00607       {         
00608         return nodes[i];
00609         break;
00610       }
00611   }
00612     
00613   return NULL;
00614 }
00615 
00616 
00617 
00618 void 
00619 Manager::initNodeFactories()
00620 {
00621 #ifdef ENABLE_VIDEOWRAPPERSRC
00622   factories.push_back(new VideoWrapperSrcFactory());
00623 #endif
00624 
00625 #ifdef ENABLE_DSVLSRC
00626   factories.push_back(new DSVLSrcFactory());
00627 #endif
00628 
00629 #ifdef ENABLE_V4LSRC
00630   factories.push_back(new V4LSrcFactory());
00631 #endif
00632 
00633 #ifdef ENABLE_V4L2SRC
00634   factories.push_back(new V4L2SrcFactory());
00635 #endif
00636 
00637 #ifdef ENABLE_GLUTSINK
00638   factories.push_back(new GLUTSinkFactory());
00639 #endif
00640 
00641 #ifdef ENABLE_GL_TEXTURE_2D_SINK
00642   factories.push_back(new GL_TEXTURE_2D_SinkFactory());
00643 #endif
00644 
00645 #ifdef ENABLE_TESTSRC
00646   factories.push_back(new TestSrcFactory());
00647 #endif
00648 
00649 #ifdef ENABLE_VIDEOSINK
00650   factories.push_back(new VideoSinkFactory());
00651 #endif
00652 
00653 #ifdef ENABLE_SPECTECSRC
00654   factories.push_back(new SpectecSrcFactory());
00655 #endif
00656 
00657 #ifdef ENABLE_IMAGESRC
00658   factories.push_back(new ImageSrcFactory());
00659 #endif
00660 
00661 #ifdef ENABLE_OPENCV
00662   factories.push_back(new OpenCVSrcFactory());
00663 #endif
00664 
00665 }
00666 
 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