Manager.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00038
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
00124 glContext=NULL;
00125 glContextChanged=false;
00126 #ifdef LINUX
00127 dsp=NULL;
00128 #endif
00129 }
00130
00131
00132 Manager::~Manager()
00133 {
00134
00135 for(int i=(int)(nodes.size())-1;i>=0;i--)
00136 {
00137
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
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
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
00312 isUse=true;
00313 useName=attribute->Value();
00314 break;
00315 }
00316 attribute = attribute->Next();
00317 }
00318
00319 Node* curNode=NULL;
00320 if(isUse){
00321
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
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
00347
00348 curNode=nodeFactory->createNode();
00349 nodes.push_back(curNode);
00350 }
00351
00352
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
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
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
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
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
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
00531 int i;
00532 while((int)nodes->size()>0)
00533 {
00534
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
00552 for (i=0;i<(int)sortedNodes.size();i++)
00553 {
00554 nodes->push_back(sortedNodes.at(i));
00555 }
00556
00557 for(i=0;i<(int)nodes->size();i++)
00558 {
00559 nodes->at(i)->init();
00560 }
00561
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
00576 for(int i=0;i<(int)nodes->size();i++){
00577
00578 nodes->at(i)->preProcess();
00579 }
00580
00581 for(int i=0;i<(int)nodes->size();i++){
00582
00583 nodes->at(i)->process();
00584 }
00585
00586 for(int i=0;i<(int)nodes->size();i++){
00587
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