00001 /* 00002 * This file contains class that represents thread with camera input. 00003 * 00004 * Author: 00005 * Tomas Mrkvicka 00006 * xmrkvi03@stud.fit.vutbr.cz 00007 * 00008 */ 00009 #include <cassert> 00010 00011 #include "pipeline/CameraThread.h" 00012 00013 //////////////////////////////////////////////////////////////////////////////// 00014 //////////////////////////////////////////////////////////////////////////////// 00015 //////////////////////////////////////////////////////////////////////////////// 00016 // TCameraThread 00017 00018 /** Staticka metoda pro beh vlakna kamery. 00019 * 00020 * Tato metoda je spustena metodou start a v ramci jejiho provadeni dochazi ke generovani novych 00021 * snimku, ktere jsou zasilany dispatcheru. 00022 * 00023 * Jedine spravne ukonceni vykonani teto metody je zavolani metody Stop objektu, ktery 00024 * je predan do tela teto metody jako parametr. 00025 * 00026 * \param ptr [in] ukazatel na objekt typu TCameraThread reprezentujici 00027 * objekt zodpovedny za beh tohoto vlakna 00028 */ 00029 DWORD WINAPI TCameraThread::TCameraDLLRun(void* ptr) 00030 { 00031 //ziskame ukazatel na kameru 00032 TCameraThread * cam = (TCameraThread*)ptr; 00033 00034 //smycka bezi dokud neni vlakno ukonceno pres metodu stop 00035 while( cam->m_isRunning ) 00036 { 00037 //tady ziskavame snimky a posilame je do dispacheru 00038 00039 //ziskame volny snimek z alokatoru 00040 TImageSetReal * img = cam->m_manager->GetImageSet(); 00041 if ( img ) 00042 { 00043 //mame snimek 00044 00045 //naplnime snimek daty 00046 cam->m_camera->GetData( img->GetRGBWrite()->GetDataWrite() ); 00047 00048 //TODO OPTIMIZE - here are 2 loops inside following methods 00049 00050 //nyni musime vytvorit dalsi datove formaty 00051 img->GetGrayWrite()->FromRGB( img->GetRGBWrite() ); 00052 img->GetARGBWrite()->FromRGB( img->GetRGBWrite() ); 00053 00054 //vytvorime obrazovy snimek a posleme do dispatcheru 00055 TFrameReal * frm = TFrameReal::Create(img); 00056 cam->m_dispatcher->SetFrame(frm); 00057 //dispatcher si udrzuje vlastni referenci - proto tuto jiz muzeme uvolnit 00058 frm->Release(); 00059 } 00060 else 00061 { 00062 //zadny snimek neni k dispozici - nic se nedeje, pouze se ceka 00063 } 00064 00065 00066 //cekame zadany casovy interval 00067 Sleep( cam->m_sleepTime ); 00068 00069 //TODO - mozna vypocitat zdrzeni ve funkci a upravit cekaci cas 00070 } 00071 00072 return 0; 00073 } 00074 //OK 2007-09-04 21:29:20 B04-315B\Tom 00075 00076 /** Konstruktor. 00077 * 00078 * Pripravi kameru k behu. Kameru je nutne spustit metodou Start(). 00079 * 00080 * \param dispatcher [in] ukazatel na platny dispatcher 00081 * \param camera [in] ukazatel na platnou kameru 00082 * \param sleepTime [in] prodleva mezi ziskanim dvou snimku v milisekundach 00083 * \param reservedFrames [in] pocet predalokovanych snimku v alokatoru snimku 00084 */ 00085 TCameraThread::TCameraThread( TDispatcher * dispatcher, TCameraAbstract * camera, DWORD sleepTime, DWORD reservedFrames ) 00086 { 00087 assert( dispatcher && camera ); 00088 00089 m_thread = NULL; 00090 m_isRunning = false; 00091 00092 m_camera = camera; 00093 m_sleepTime = sleepTime; 00094 00095 m_dispatcher = dispatcher; 00096 00097 //vytvorime manager snimku 00098 if ( 0 == reservedFrames ) reservedFrames = 1; //chceme alespon 1 snimek 00099 m_manager = new TImageSetManager( (DWORD)camera->GetWidth(), (DWORD)camera->GetHeight(), reservedFrames ) ; 00100 } 00101 //OK 2007-08-25 15:25:29 B04-315B\Tom 00102 00103 /** Zruseni objektu. 00104 * 00105 * \warning Destruktor znici manager snimku. Je tedy dulezite, aby se v aplikaci 00106 * v dobe volani teto metody nevyskytovaly zadne snimky. 00107 * Pred zrusenim by tedy kamera mela byt zastavena metodou Stop(). 00108 */ 00109 TCameraThread::~TCameraThread(void) 00110 { 00111 if(m_thread) 00112 { 00113 //kamera bezi - musime zastavit 00114 Stop(); 00115 } 00116 00117 //odstranime manager snimku 00118 delete m_manager; 00119 } 00120 //OK 2007-08-25 15:25:51 B04-315B\Tom 00121 00122 /** Spusteni kamery. 00123 * 00124 * Metoda vraci TRUE pokud byla kamera uspesne spustena nebo jiz bezi. 00125 */ 00126 BOOL TCameraThread::Start(void) 00127 { 00128 if( ! m_thread ) 00129 { 00130 //kamera nebezi 00131 00132 //spustime vypocetni vlakno 00133 m_thread = new TThread; 00134 m_isRunning = true; 00135 00136 BOOL res = m_thread->Run((FUNC_PTR)TCameraDLLRun,(void*)this); 00137 00138 if(res) 00139 { 00140 return TRUE; 00141 } 00142 else 00143 { 00144 m_isRunning = false; 00145 delete m_thread; 00146 m_thread = NULL; 00147 00148 return FALSE; 00149 } 00150 } 00151 else 00152 { 00153 //jednotka uz bezi 00154 return TRUE; 00155 } 00156 } 00157 //OK 2007-08-25 15:26:03 B04-315B\Tom 00158 00159 /** Zastaveni kamery. 00160 * 00161 * Metoda znici vypocetni vlakno. 00162 * 00163 * Vraci TRUE pokud bylo vlakno uspesne zastaveno. 00164 */ 00165 BOOL TCameraThread::Stop(void) 00166 { 00167 if( m_thread ) 00168 { 00169 //kamera bezi - nastavime stav pro zastaveni 00170 m_isRunning = false; 00171 00172 //cekame na ukonceni vlakna 00173 while( ! m_thread->IsTerminated() ) 00174 { 00175 Sleep(20); 00176 }; 00177 00178 //znicime vlakno 00179 //nyni jednotka stoji - ukoncime ji 00180 m_thread->Finish(); 00181 delete m_thread; 00182 m_thread = NULL; 00183 00184 return TRUE; 00185 } 00186 else 00187 { 00188 //vlakno neexistuje 00189 return TRUE; 00190 } 00191 } 00192 //OK 2007-08-25 15:26:09 B04-315B\Tom 00193 00194 // TCameraThread 00195 //////////////////////////////////////////////////////////////////////////////// 00196 //////////////////////////////////////////////////////////////////////////////// 00197 ////////////////////////////////////////////////////////////////////////////////