Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phNetImageWindow.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 #include <phNetImageWindow.h>
00032 
00033 #include <phNetClientThread.h>
00034 
00035 #if defined(HAVE_STDLIB_H)
00036     #include <stdlib.h>
00037 #endif
00038 #if defined(HAVE_STRING_H)
00039     #include <string.h>
00040 #endif
00041 
00042 #include <phError.h>
00043 #include <phMemory.h>
00044 #include <phPrint.h>
00045 
00046 /* ---------------------------------------------------------------------- */
00047 phNetImageWindow::phNetImageWindow( int32_t x, int32_t y,
00048                                     uint32_t w, uint32_t h,
00049                                     char *title, 
00050                                     uint32_t flags ) :
00051                 phImageWindow(x,y,w,h,title,flags )
00052 {
00053     phFUNCTION("phX11ImageWindow::phX11ImageWindow")
00054     
00055     rc = this->lock();
00056     phPRINT_RC(rc,NULL,"this->lock()");
00057 
00058     this->setName("phNetImageWindow");
00059    
00060     this->m_portNum = 55443;
00061 
00062 #if HAVE_CONFIG_H
00063     /* default YUV9, because it's going to work on the majority of 
00064      * machines, where
00065      * (phImageJPEG | phImageZLIB | phImageRGB24) will not always be 
00066      * supported */
00067     this->m_formats = phImageYUV9;
00068 #else
00069     #if HAVE_LIBJPEG
00070     this->m_formats = phImageJPEG | phImageRGB24;
00071     #elif HAVE_LIBZ
00072     this->m_formats = phImageZLIB | phImageRGB24;
00073     #else
00074     this->m_formats = phImageYUV9;
00075     #endif
00076 #endif
00077 
00078     if (this->m_title == NULL)
00079     {
00080         this->setTitle("Phission: phNetImageWindow");
00081     }
00082 
00083     rc = this->m_clientCountVar.setValue(0);
00084     phPRINT_RC(rc,NULL,"m_clientCountVar.setValue(0)");
00085 
00086 /*error:*/
00087     rc = this->unlock();
00088     phPRINT_RC(rc,NULL,"this->unlock() failed.");
00089     
00090     return;
00091 }
00092 
00093 /* ---------------------------------------------------------------------- */
00094 phNetImageWindow::~phNetImageWindow( )
00095 {
00096     phFUNCTION("phNetImageWindow::~phNetImageWindow")
00097 
00098     /* phTHIS_LOOSE_LOCK(); */
00099 }
00100 
00101 /* ---------------------------------------------------------------------- */
00102 int phNetImageWindow::setPort( uint32_t portNum )
00103 {
00104     phFUNCTION("phNetImageWindow::setPort")
00105 
00106     rc = this->lock();
00107     phPRINT_RC(rc,NULL,"this->lock()");
00108 
00109     if ((portNum > 65535) || (portNum <= 0))
00110     {
00111         phCHECK_RC(-1,NULL,"Invalid port number. Port number range: 1->66535.");
00112     }
00113 
00114     this->m_portNum = portNum;
00115     
00116     rc = this->unlock();
00117     phPRINT_RC(rc,NULL,"this->unlock()");
00118 
00119     return phSUCCESS;
00120 error:
00121     rc = this->unlock();
00122     phPRINT_RC(rc,NULL,"this->unlock()");
00123     
00124     return phFAIL;
00125 
00126 }
00127 
00128 /* ---------------------------------------------------------------------- */
00129 uint32_t phNetImageWindow::getPort( ) 
00130 {
00131     return this->m_portNum; 
00132 }
00133 
00134 /* ---------------------------------------------------------------------- */
00135 int phNetImageWindow::isOpen()
00136 {
00137     return this->isRunning();
00138 }
00139 
00140 /* ---------------------------------------------------------------------- */
00141 uint32_t phNetImageWindow::getWidth()
00142 {
00143     phFUNCTION("phNetImageWindow::getWidth()")
00144     uint32_t returnval = 0;
00145     
00146     rc = this->lock();
00147     phPRINT_RC(rc,NULL,"this->lock()");
00148 
00149     returnval = this->m_image.getWidth();
00150     
00151     rc = this->unlock();
00152     phPRINT_RC(rc,NULL,"this->unlock()");
00153 
00154     return returnval;
00155 }
00156 /* ---------------------------------------------------------------------- */
00157 uint32_t phNetImageWindow::getHeight()
00158 {
00159     phFUNCTION("phNetImageWindow::getHeight()")
00160     uint32_t returnval = 0;
00161     
00162     rc = this->lock();
00163     phPRINT_RC(rc,NULL,"this->lock()");
00164 
00165     returnval = this->m_image.getHeight();
00166     
00167     rc = this->unlock();
00168     phPRINT_RC(rc,NULL,"this->unlock()");
00169 
00170     return returnval;
00171 }
00172 
00173 /* ---------------------------------------------------------------------- */
00174 phImage *phNetImageWindow::getImage()
00175 { 
00176     return &(this->m_convImage);
00177 }
00178 
00179 /* ---------------------------------------------------------------------- */
00180 int phNetImageWindow::setFormats( uint32_t formats )
00181 {
00182     phFUNCTION("phNetImageWindow::setFormats")
00183     
00184     rc = this->lock();
00185     phPRINT_RC(rc,NULL,"this->lock()");
00186 
00187     this->m_formats = formats;
00188 
00189     rc = this->unlock();
00190     phPRINT_RC(rc,NULL,"this->unlock()");
00191 
00192     return phSUCCESS;
00193 /*
00194 error:
00195     rc = this->unlock();
00196     phPRINT_RC(rc,NULL,"this->unlock()");
00197     
00198     return phFAIL;
00199 */
00200 }
00201 
00202 /* ---------------------------------------------------------------------- */
00203 int phNetImageWindow::private_show()
00204 {
00205     /* 
00206      * We are locked when we get into a "private" method; Locking is done 
00207      * as a policy in any public interface method that calls a private 
00208      * (implementation specific) method 
00209     int locked = 1;
00210      */
00211     return phSUCCESS;
00212 }
00213 
00214 /* ---------------------------------------------------------------------- */
00215 int phNetImageWindow::private_hide()
00216 {
00217     /* 
00218      * We are locked when we get into a "private" method; Locking is done 
00219      * as a policy in any public interface method that calls a private 
00220      * (implementation specific) method 
00221     int locked = 1;
00222      */
00223     return phSUCCESS;
00224 }
00225 
00226 /* ---------------------------------------------------------------------- */
00227 int phNetImageWindow::private_redraw()
00228 {
00229     /* 
00230      * We are locked when we get into a "private" method; Locking is done 
00231      * as a policy in any public interface method that calls a private 
00232      * (implementation specific) method 
00233     int locked = 1;
00234      */
00235     return phSUCCESS;
00236 }
00237 
00238 /* ---------------------------------------------------------------------- */
00239 int phNetImageWindow::private_update()
00240 {
00241     phFUNCTION("phNetImageWindow::private_update")
00242     intmax_t    return_value= 0;
00243     /* 
00244      * We are locked when we get into a "private" method; Locking is done 
00245      * as a policy in any public interface method that calls a private 
00246      * (implementation specific) method 
00247      */
00248     int locked = 1;
00249 
00250     phTHIS_UNLOCK(locked);
00251     
00252     rc = this->m_clientCountVar.waitForValue(0,phCHECK_NE,&return_value);
00253     /* if rc == 0, then we were woken up because we're not supposed
00254      * to return unless the Value is NOT 0 */
00255     if (return_value == 0)
00256     {
00257         /* This the right thing TODO? */
00258         /* or should we just go and convert the image */
00259         phTHIS_LOCK(locked);
00260         return 1;
00261     }
00262     else if (rc == phConditionCounter_WAKEUP)
00263     {
00264         phTHIS_LOCK(locked);
00265         return 1;
00266     }
00267     else
00268     {
00269         phTHIS_LOCK(locked);
00270         phCHECK_RC(rc,NULL,"m_clientCountVar.waitForValue(0,phCHECK_NE);");
00271     }
00272     
00273     /* m_convImage is the image that is set by the phDisplayInterface with
00274      * the incoming data from the live source */
00275     if (this->m_convImage.isNull() == 0)
00276     {
00277         /* For this image window, convert the data to the specified
00278          * format and then swap data to the image that all the client
00279          * threads are listening to */
00280         rc = this->m_convImage.convert(this->m_formats);
00281         phPRINT_RC(rc,NULL,"m_convImage.convert() failed.");
00282         
00283         rc = this->m_image.swapImage(this->m_convImage);
00284         phPRINT_RC(rc,NULL,"m_image->swapImage() failed.");
00285 
00286         /* wait for someone to enter the queue for the image update */
00287         rc = this->m_image.getWaitingCounter()->waitForValue(0,phCHECK_GT);
00288         phPRINT_RC(rc,NULL,"m_image.getWaitingCounter().waitForValue(0,phCHECK_GT);");
00289     }
00290     
00291     phTHIS_LOCK(locked);
00292     return phSUCCESS;
00293 error:
00294     return phFAIL;
00295 }
00296 
00297 /* ---------------------------------------------------------------------- */
00298 int phNetImageWindow::private_resize( uint32_t w, uint32_t h)
00299 {
00300     /* 
00301      * We are locked when we get into a "private" method; Locking is done 
00302      * as a policy in any public interface method that calls a private 
00303      * (implementation specific) method 
00304     int locked = 1;
00305      */
00306     return phSUCCESS;
00307 }
00308 
00309 /* ---------------------------------------------------------------------- */
00310 int phNetImageWindow::private_move( int32_t x, int32_t y)
00311 {
00312     /* 
00313      * We are locked when we get into a "private" method; Locking is done 
00314      * as a policy in any public interface method that calls a private 
00315      * (implementation specific) method 
00316     int locked = 1;
00317      */
00318     return phSUCCESS;
00319 }
00320 
00321 /* ---------------------------------------------------------------------- */
00322 int phNetImageWindow::private_minsize( uint32_t min_w, uint32_t min_h)
00323 {
00324     /* 
00325      * We are locked when we get into a "private" method; Locking is done 
00326      * as a policy in any public interface method that calls a private 
00327      * (implementation specific) method 
00328     int locked = 1;
00329      */
00330     return phSUCCESS;
00331 }    
00332 
00333 
00334 /* ---------------------------------------------------------------------- */
00335 int phNetImageWindow::wakeup()
00336 {
00337     phFUNCTION("phNetImageWindow::wakeup()")
00338 
00339     /* Don't lock it, we're trying to wake the encapsulated thread up w/o
00340      * trying to deadlock the process at the same time */
00341     /* phTHIS_LOOSE_LOCK(); */
00342 
00343     this->m_server.wakeup();
00344 
00345     rc = this->m_clientCountVar.wakeup();
00346     phPRINT_RC(rc,NULL,"m_clientCountVar.wakeup()");
00347     
00348     /* This really wakes up other threads because it'll only be blocking
00349      * in a method that is called by another thread */
00350     rc = this->m_convImage.wakeup_self();
00351     phPRINT_RC(rc,NULL,"m_convImage.wakeup_self() failed.");
00352 
00353     rc = this->phImageWindow::wakeup();
00354     phPRINT_RC(rc,NULL,"this->phImageWindow::wakeup()");
00355     
00356     /* phTHIS_LOOSE_UNLOCK(); */
00357 
00358     return phSUCCESS;
00359 }
00360 
00361 /* ---------------------------------------------------------------------- */
00362 int phNetImageWindow::run()
00363 {
00364     phFUNCTION("phNetImageWindow::run()")
00365 
00366     /* Display stuff */
00367     /* create the server communications object */
00368     phNetClientThread   *clientThread   = NULL;
00369     phSocket            *clientComms    = NULL;
00370 
00371     /* INITIALIZE STUFF HERE   x, y, w, h, title */
00372     //phPROGRESS("Thread started\n");
00373 
00374     rc = this->m_server.setBackLog(10);
00375     phPRINT_RC(rc,NULL,"m_server.setBackLog(%d)",10);
00376     
00377     rc = this->m_server.listen(this->m_portNum);
00378     phCHECK_RC(rc,NULL,"m_server.listen(port:%d) failed", this->m_portNum);
00379 
00380     /* set non-blocking for the server comms */
00381     this->m_server.setBlocking(phBLOCK); /* TODO may need phNONBLOCK */
00382     
00383     //phPROGRESS("Listening for connections on port %d\n", this->m_portNum);
00384    
00385     this->m_client_running = 1;
00386     
00387     rc = this->signal_running();
00388     phPRINT_RC(rc,NULL,"this->signal_running()");
00389 
00390     /* End when server_handler is done. */
00391     while (this->isRunning())
00392     {
00393         rc              = 0;
00394         clientThread    = NULL;
00395         clientComms     = NULL;
00396         clientComms     = this->m_server.accept();
00397         if (!this->isRunning())
00398         {
00399             phDelete(clientComms);
00400             continue;
00401         }
00402         phCONT_NULLPTR(clientComms,NULL,
00403             "m_server.accept() failed to accept client connection\n\n");
00404 
00405         phPRINT("Accept\n");
00406 
00407         clientThread = new phNetClientThread();
00408         if (clientThread == NULL)
00409         {
00410             phDelete(clientComms);
00411             phCONT_NULLPTR(clientThread,"new phNetClientThread",
00412                 "new failed to alloc clientThread.");
00413         }
00414 
00415         /* Set blocking for the client */
00416         clientComms->setBlocking(phBLOCK);
00417       
00418         /* TODO: use a data lock ??? */
00419         rc = this->lock();
00420         phPRINT_RC(rc,NULL,"this->lock()");
00421 
00422         rc = clientThread->set( &this->m_clientCountVar,
00423                                 clientComms,
00424                                 this->phImageWindow::getImage(),
00425                                 this->m_title,
00426                                 &this->m_client_running );
00427         phPRINT_RC(rc,NULL,"clientThread->set failed.");
00428         
00429         rc = this->unlock();
00430         phPRINT_RC(rc,NULL,"this->unlock()");
00431        
00432         rc = clientThread->start(phDETACHED);
00433         phPRINT_RC(rc,NULL,"clientThread->start(phDETACHED) failed.");
00434 
00435     } 
00436     
00437     DEBUG_PRINT("Thread returning cleanly\n");
00438     
00439     this->m_client_running = 0;
00440 
00441     return phSUCCESS;
00442     
00443 error:
00444     phPROGRESS("Thread returning with error\n");
00445     
00446     this->m_client_running = 0;
00447 
00448     rc = this->signal_error();
00449     phPRINT_RC(rc,NULL,"this->signal_error()");
00450 
00451     return phFAIL;
00452 }
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:03 2007 for phission by  doxygen 1.4.4