imagebase.cc

00001 /*
00002  *  Player - One Hell of a Robot Server
00003  *  Copyright (C) 2000  Brian Gerkey et al
00004  *                      gerkey@usc.edu    
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00022 //
00023 // Desc: base driver for image processing and transform drivers
00024 // Author: Toby Collett
00025 // Date: 15 Feb 2004
00026 // CVS: $Id: imagebase.cc 4367 2008-02-18 19:42:49Z thjc $
00027 //
00029 
00030 #include <stddef.h>
00031 #include <string.h>
00032 #include <assert.h>
00033 #include "imagebase.h"
00034 #include <libplayerxdr/playerxdr.h>
00035 #if HAVE_JPEGLIB_H
00036 #include <libplayerjpeg/playerjpeg.h>
00037 #endif
00038 
00040 // Constructor
00041 
00042 ImageBase::ImageBase(ConfigFile *cf, int section, bool overwrite_cmds, size_t queue_maxlen, int interf)
00043         : Driver(cf, section, overwrite_cmds, queue_maxlen, interf)
00044 {
00045   memset(&this->camera_addr, 0, sizeof(player_devaddr_t));
00046   stored_data.image = NULL;
00047   stored_data.image_count = 0;
00048   HaveData = false;
00049 
00050   // Must have an input camera
00051   if (cf->ReadDeviceAddr(&this->camera_addr, section, "requires",
00052                        PLAYER_CAMERA_CODE, -1, NULL) != 0)
00053   {
00054     this->SetError(-1);    
00055     return;
00056   }
00057 
00058 }
00059 
00060 
00061 ImageBase::ImageBase(ConfigFile *cf, int section, bool overwrite_cmds, size_t queue_maxlen)
00062         : Driver(cf, section, overwrite_cmds, queue_maxlen)
00063 {
00064   memset(&this->camera_addr, 0, sizeof(player_devaddr_t));
00065   stored_data.image = NULL;
00066   stored_data.image_count = 0;
00067   HaveData = false;
00068 
00069   // Must have an input camera
00070   if (cf->ReadDeviceAddr(&this->camera_addr, section, "requires",
00071                        PLAYER_CAMERA_CODE, -1, NULL) != 0)
00072   {
00073     this->SetError(-1);    
00074     return;
00075   }
00076 
00077 }
00078 
00079 
00081 // Set up the device (called by server thread).
00082 int ImageBase::Setup()
00083 {
00084   // Subscribe to the camera.
00085   if (Device::MatchDeviceAddress (camera_addr, device_addr))
00086   {
00087     PLAYER_ERROR ("attempt to subscribe to self");
00088     return -1;
00089   }
00090   if (!(camera_driver = deviceTable->GetDevice (camera_addr)))
00091   {
00092     PLAYER_ERROR ("unable to locate suitable camera device");
00093     return -1;
00094   }
00095   if (camera_driver->Subscribe (InQueue) != 0)
00096   {
00097     PLAYER_ERROR ("unable to subscribe to camera device");
00098     return -1;
00099   }
00100 
00101   StartThread();
00102 
00103   return 0;
00104 }
00105 
00107 // Shutdown the device (called by server thread).
00108 int ImageBase::Shutdown()
00109 {
00110   StopThread();
00111         
00112   camera_driver->Unsubscribe(InQueue);
00113 
00114   return 0;
00115 }
00116 
00118 // Process an incoming message
00119 int ImageBase::ProcessMessage (QueuePointer &resp_queue, player_msghdr * hdr, void * data)
00120 {
00121   uint32_t new_image_count;
00122   player_camera_data_t * compdata = reinterpret_cast<player_camera_data_t *>(data);
00123 
00124   assert(hdr);
00125   assert(compdata);
00126 
00127   if(Message::MatchMessage (hdr, PLAYER_MSGTYPE_DATA, PLAYER_CAMERA_DATA_STATE, camera_addr))
00128   {
00129         Lock();
00130         if (!HaveData)
00131         {
00132             this->stored_data.width = (compdata->width);
00133             this->stored_data.height = (compdata->height);
00134             this->stored_data.fdiv = (compdata->fdiv);
00135 #if HAVE_JPEGLIB_H
00136             if (compdata->compression != PLAYER_CAMERA_COMPRESS_JPEG)
00137             {
00138 #endif
00139                 this->stored_data.compression = (compdata->compression);
00140                 this->stored_data.format = (compdata->format);
00141                 this->stored_data.bpp = (compdata->bpp);
00142                 if ((this->stored_data.image_count) != (compdata->image_count))
00143                 {
00144                     this->stored_data.image_count = (compdata->image_count);
00145                     if (this->stored_data.image) delete [](this->stored_data.image);
00146                     this->stored_data.image = NULL;
00147                     if (this->stored_data.image_count)
00148                     {
00149                         this->stored_data.image = new uint8_t[this->stored_data.image_count];
00150                         assert(this->stored_data.image);
00151                     }
00152                 }
00153                 if (this->stored_data.image_count)
00154                 {
00155                     assert(this->stored_data.image);
00156                     memcpy(this->stored_data.image, compdata->image, this->stored_data.image_count);
00157                 }
00158 #if HAVE_JPEGLIB_H
00159             } else
00160             {
00161                 this->stored_data.compression = PLAYER_CAMERA_COMPRESS_RAW;
00162                 this->stored_data.format = PLAYER_CAMERA_FORMAT_RGB888;
00163                 this->stored_data.bpp = 24;
00164                 new_image_count = (this->stored_data.width) * (this->stored_data.height) * 3;
00165                 if ((this->stored_data.image_count) != new_image_count)
00166                 {
00167                     this->stored_data.image_count = new_image_count;
00168                     if (this->stored_data.image) delete [](this->stored_data.image);
00169                     this->stored_data.image = NULL;
00170                     if (this->stored_data.image_count)
00171                     {
00172                         this->stored_data.image = new uint8_t[this->stored_data.image_count];
00173                         assert(this->stored_data.image);
00174                     }
00175                 }
00176                 if (this->stored_data.image_count)
00177                 {
00178                     assert(this->stored_data.image);
00179                     jpeg_decompress(reinterpret_cast<unsigned char *>(this->stored_data.image),
00180                                     this->stored_data.image_count,
00181                                     reinterpret_cast<unsigned char *>(compdata->image),
00182                                     compdata->image_count);             
00183                 }
00184             }
00185 #endif
00186             HaveData = true;
00187         }
00188         Unlock();
00189     return 0;
00190   }
00191   return -1;
00192 }
00193 
00194 void ImageBase::Main()
00195 {
00196         for(;;)
00197         {
00198                 pthread_testcancel();
00199                 
00200                 InQueue->Wait();
00201                 
00202                 ProcessMessages();
00203                 
00204                 Lock();
00205                 if (HaveData)
00206                 {
00207                         Unlock();
00208                         ProcessFrame();
00209                         Lock();
00210                         HaveData = false;
00211                 }
00212                 Unlock();
00213         }
00214         
00215 }

Last updated 12 September 2005 21:38:45