prip/include/IPCamera.h

Go to the documentation of this file.
00001 
00008 #ifndef PRIP_IPCAMERA_H
00009 #define PRIP_IPCAMERA_H
00010 
00011 #include "prip.h"
00012 #include "Util.h"
00013 #include <pinet.h>
00014 #include <string>
00015 #include <vector>
00016 #include <sstream>
00017 #include <iostream>
00018 
00019 namespace prip {
00020 
00027 class MJPEGStream : public pt::thread
00028 {
00029 public:
00034    MJPEGStream(pt::instm& stream) : pt::thread(false),
00035       mStream(stream), mCancel(false),mFrameNr(0)
00036    {}
00037 
00038    virtual ~MJPEGStream(void)
00039    {
00040       cancel();
00041       waitfor();
00042    }
00043 
00049    void cancel(void)
00050    {
00051       mCancel = true;
00052    }
00053 
00060    std::string getJPEG(void) const
00061    {
00062       pt::scopelock x(mMutexJPEG);
00063       return currentJPEG;
00064    }
00065 
00073    int getFrameNr(void) const
00074    {
00075       pt::scopelock x(mMutexJPEG);
00076       return mFrameNr;
00077    }
00078 
00084    void setFrameNr(int newFrameNr = 0)
00085    {
00086       pt::scopelock x(mMutexJPEG);
00087       mFrameNr = newFrameNr;
00088    }
00089 
00094    void resetFrameNr(void)
00095    {
00096       setFrameNr();
00097    }
00098 
00099 
00100 protected:
00104    virtual void execute(void)
00105    {
00106       std::stringstream oss;
00107       bool started(false);
00108 
00109       while (!mStream.get_eof() && !mCancel)
00110       {
00111          unsigned char cur = mStream.get();
00112          if (mStream.get_eof()) std::clog << "EOF!" << std::endl;
00113          unsigned char preview = mStream.preview();
00114          if (mStream.get_eof()) std::clog << "EOF!" << std::endl;
00115 
00116 
00117          if (cur==0xFF)
00118          {
00119             if (started && (preview == 0xD9))
00120             {
00121                
00122                started = false;
00123                oss.put(cur);
00124                
00125 
00126                cur = mStream.get();
00127                oss.put(cur);
00128                putJPEG(oss.str());
00129 
00130                // clear ostringstream
00131                oss.seekp(0);
00132             } else if (!started && ( preview == 0xD8))
00133             {
00134                started = true;
00135             }
00136             
00137          }
00138 
00139          if (started) 
00140          {
00141             oss.put(cur);
00142             
00143          }
00144       }
00145    }
00146 
00147    
00151    virtual void cleanup(void)
00152    {}
00153    
00154    pt::instm&  mStream;
00155    bool     mCancel;
00156 
00157    std::string currentJPEG;
00158 
00159 private:
00160    mutable pt::mutex mMutexJPEG;
00161    int mFrameNr;
00162    
00163    void putJPEG(const std::string& newJPEG)
00164    {  
00165       pt::scopelock x(mMutexJPEG);
00166       currentJPEG = newJPEG;
00167       std::clog << "retrieved new image frame-Nr"<<mFrameNr+1 << std::endl;
00168       mFrameNr++;
00169    }
00170 };
00171 
00179 class IPCamera
00180 {
00181 public:
00182    
00190    IPCamera(std::string address, int port, std::string username="", 
00191       std::string password="") : mAddress(address), mPort(port), mUsername(username),
00192       mPassword(password), mClient(mAddress.c_str(),mPort)
00193    {}
00194 
00195    
00200    IPCamera(const IPCamera& other) : 
00201    mAddress(other.mAddress), mPort(other.mPort), mUsername(other.mUsername),
00202       mPassword(other.mPassword), mClient(mAddress.c_str(),mPort)
00203    {
00204    }
00205 
00210    IPCamera& operator=(const IPCamera& other) 
00211    {
00212       if (&other==this)
00213          return *this;
00214 
00215       mAddress = other.mAddress;
00216       mPort = other.mPort;
00217       mUsername = other.mUsername;
00218       mPassword = other.mPassword;
00219 
00220       mClient.set_port(mPort);
00221       mClient.set_host(mAddress.c_str());
00222    }
00223 
00227    virtual ~IPCamera(void);
00228 
00229 
00243    void post(std::string site, 
00244       const std::vector<std::string>& parameters, 
00245       const std::vector<std::string>& values,
00246       bool close=false);
00247 
00261    void post(std::string site, std::string parameter, std::string value, bool close = false)
00262    {
00263       std::vector<std::string> ps(1), v(1);
00264       ps.push_back(parameter);
00265       v.push_back(value);
00266       post(site,ps,v,close);
00267    }
00268    
00281    void get(const std::string site, bool close=false);
00282    
00289    void setUsername(const std::string username) {mUsername = username;}
00290 
00296    void setPassword(const std::string password) {mPassword = password;}
00297 
00298 
00303    pt::ipstream& getResult(void) {return mClient;}
00304 
00313    virtual std::string getImage(void) = 0;
00314 
00315 private:
00319    IPCamera(void) {}
00320    
00321    std::string    mAddress;
00322    int            mPort;
00323 
00324    std::string    mUsername;
00325    std::string    mPassword;
00326 
00327    std::string    mCurrentImg;
00328 
00329 protected:
00331    pt::ipstream   mClient;
00332 
00333 };
00334 
00336 typedef std::vector<unsigned char> ViscaCommand;
00337 
00349 class ViscaControl
00350 {
00351 public:
00352    
00353 
00355    static const int Head = 0x81;
00356    
00358    static const int Term = 0xFF;
00359 
00360    static const bool ON = true;
00361    static const bool OFF = false;
00362 
00364    enum Type {TCommand = 0x01, TInquiry = 0x09};
00365 
00367    enum Category {CInterface = 0x00, CCamera = 0x04, CPanTilt = 0x06};
00368 
00374    void CAM_Power(bool on);
00375 
00379    void CAM_ZoomStop(void);
00380 
00388    void CAM_ZoomIn(int speed = -1);
00389 
00397    void CAM_ZoomOut(int speed = -1);
00398 
00406    void CAM_ZoomTo(int pos);
00407 
00408 
00412    void CAM_FocusStop(void);
00413 
00419    void CAM_FocusFar(int speed = -1);
00420 
00426    void CAM_FocusNear(int speed = -1);
00427 
00436    bool CAM_FocusDirect(int pos);
00437    
00439    enum FocusMode{
00441       FMManual,
00442 
00444       FMAuto,
00445 
00447       FMSwitch,
00448       
00456       FMOnePushTrigger,
00457 
00459       FMInfinity,
00460 
00462       FMNearLimit
00463    };
00464 
00474    bool CAM_FocusMode(FocusMode mode, int limit=0);
00475 
00479    enum AFSensitivity {
00486       AFSNormal=0x02, 
00487       
00495       AFSLow=0x03    
00496    };
00497 
00503    void CAM_AFSensitivity(AFSensitivity mode);
00504 
00508    enum AFMode {
00510       AFNormal, 
00517       AFInterval, 
00518       AFZoomTrigger,
00519       AFActiveInterval};
00520 
00528    void CAM_AFMode(AFMode mode, int time, int interval);
00529 
00530    
00531    enum InitializationMode {
00533       IMLens = 0x01, 
00535       IMCompScan = 0x02};
00536    
00543    void CAM_Initialize(InitializationMode mode);
00544 
00545 
00549    enum WBMode {
00558       WBAuto=0,         
00559 
00561       WBIndoor,         
00562       
00564       WBOutdoor,        
00565       
00578       WBOnePushWB,      
00579       
00581       WBATW,            
00582       
00588       WBManual,         
00589       
00591       WBOnePushTrigger  
00592    };
00593 
00599    void CAM_WB(WBMode mode);
00600 
00604    enum GainMode {GainReset = 0, GainUp = 0x02, GainDown=0x03, GainDirect = 0xFF};
00605    
00613    void CAM_RGain(GainMode mode, int gain);
00614 
00622    void CAM_BGain(GainMode mode, int gain);
00623 
00624 
00625    enum AEMode {
00627       AEAuto=0x00,
00628 
00630       AEManual=0x03,
00631 
00632       /*Shutter Priority Automatic Exposure Mode - Variable Shutter Speed, Auto Iris and Gain (1/1 to 1/10000 sec, 22 steps, std. shutter: 16 setps, slow shutter, 6 steps)
00633        *
00634        * The shutter speed can be set freeely by the user to a 
00635        * total of 22 steps - 16 high speed and 6 low speeds.
00636        * when the slow shutter is set, the speed can be 1/30, 1/15,
00637        * 1/8, or 1/4 sec. The picture output is read at a normal rate from
00638        * the memory. The memory is updated at a low rate from the CCD.
00639        * AF capability is low. In high speed mode, the shutter speed
00640        * can be set up to 1/10000 sec. The iris and gain are set automatically,
00641        * according to the brightness
00642        */
00643       AEShutter=0x0A,
00644 
00646       AEIris=0x0B,
00647 
00649       AEBright=0x0D
00650    };
00651    
00657    void CAM_AE(AEMode mode);
00658    
00659    
00668    void CAM_AutoSlowShutter(bool on);
00669 
00674    enum ChangeParam
00675    {
00676       CPReset = 0x00,
00677       CPUp = 0x02,
00678       CPDown = 0x03,
00679       CPDirect = 0xFF
00680    };
00681 
00716    void CAM_Shutter(ChangeParam cp, int data=0);
00717 
00740    void CAM_Iris(ChangeParam cp, int data=0);
00741 
00771    void CAM_Gain(ChangeParam cp, int pos=0);
00772 
00814    void CAM_Bright(ChangeParam cp, int data=0);
00815 
00824    void CAM_ExpComp(bool on);
00825 
00851    void CAM_SetExpComp(ChangeParam cp, int data=0);
00852 
00859    void CAM_BackLight(bool on);
00860 
00875    void CAM_SpotAE(bool on);
00876 
00888    bool CAM_SetSpotAE(int X, int Y);
00889 
00900    void CAM_Aperture(ChangeParam cp, int data=0);
00901 
00906    void CAM_LR_Reverse(bool on);
00907 
00916    void CAM_Freeze(bool on);
00917 
00918    enum PictureEffect {
00920       PEOff = 0x02,
00921 
00923       PENegArt = 0x03,
00924 
00926       PEMonochrome = 0x04
00927    };
00928 
00934    void CAM_PictureEffect(PictureEffect pe);
00935 
00945    void CAM_ICR(bool on);
00946 
00960    void CAM_AutoICR(bool on);
00961 
00962    void CAM_Stabilizer(bool on);
00963 
00964    bool CAM_Memory_Reset(int presetPosition);
00965    bool CAM_Memory_Set(int presetPosition);
00966    bool CAM_Memory_Recall(int presetPosition);
00967 
00968    void CAM_CUSTOM_Set(void);
00969    void CAM_CUSTOM_Reset(void);
00970 
00971 
00979    void PanTiltAutoSpeed(bool on);
00980 
00985    enum Direction {Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight, Stop, Home};
00986 
00998    void PanTiltDrive(Direction dir, int panSpeed=0xFF, int tiltSpeed=0xFF);
00999 
01006    void PanTiltAbsolutePosition(int panSpeed, int tiltSpeed, int panPos, int tiltPos);
01007 
01014    void PanTiltRelativePosition(int panSpeed, int tiltSpeed, int panPos, int tiltPos);
01015 
01026    bool PanTiltGotoPreset(int pos, int panSpeed, int tiltSpeed);
01027 
01028 
01034    static std::string ViscaToString(const ViscaCommand& vc)
01035    {
01036       std::ostringstream cmd;
01037       
01038       for (ViscaCommand::const_iterator it = vc.begin(); it!=vc.end(); it++)
01039       {
01040          cmd << std::hex;
01041          cmd.width(2);
01042          cmd.fill('0');
01043          cmd << static_cast<short>(*it);
01044       }
01045       return cmd.str();
01046    }
01047 
01053    virtual std::ostream& operator<<(std::ostream& out)
01054    {
01055       out << ViscaToString(mCmd);
01056       return out;
01057    }
01058 
01059 protected:
01060    ViscaCommand mCmd;
01061    
01071    virtual void initCommand(Type t, Category c)
01072    {
01073       mCmd.clear();
01074       mCmd.push_back(Head);
01075       mCmd.push_back(t);
01076       mCmd.push_back(c);
01077    }
01078 
01083    virtual void termCommand()
01084    {
01085       mCmd.push_back(0xFF);
01086    }
01087 
01096    virtual void sendCommand()
01097    {
01098       std::cout << ViscaToString(mCmd) << std::endl;
01099    }
01100 
01101 };
01102 
01103 
01108 class ViscaIP : public IPCamera, public ViscaControl
01109 {
01110 
01111 public:
01126    ViscaIP(std::string address, int port, std::string cgiscript="/command/ptzf.cgi",std::string imgpath="/.jpg",std::string streampath="/mjpeg",
01127       std::string username="", std::string password="") : 
01128    IPCamera(address,port,username,password), mSite(cgiscript),mImgPath(imgpath),mStreamPath(streampath),mStreamHandler(mClient)
01129    {}
01130    
01131 
01132    std::string getImage(void)
01133    {
01134       get(mImgPath,false);
01135       std::cout << mClient.get_status() << std::endl;
01136       while (!mClient.get_eof())
01137       {
01138          std::cout << mClient.get_status() << std::endl;
01139          const int bufferSize = 100*1024;
01140          char buffer[bufferSize];
01141          int size = mClient.read(buffer,bufferSize);
01142          std::ostringstream oss;
01143          oss.write(buffer,size);
01144          std::cout << size << ": "<< std::endl;
01145          std::cout << oss.str() << std::endl << "----------" << std::endl << std::endl;
01146       } 
01147       std::cout << mClient.get_status() << std::endl;
01148       std::cout << "done";
01149       mClient.close();
01150       return "";
01151    }
01152 
01156    std::string getNextImage(void)
01157    {
01158       if (mClient.get_active()!=true)
01159          startMJPEGStream();
01160 
01161       std::string jpeg;
01162       do
01163       {
01164          jpeg = mStreamHandler.getJPEG();
01165          if (jpeg=="") pt::psleep(100);
01166          if (mStreamHandler.get_running()!=true) break;
01167       } while (jpeg=="");
01168 
01169       return jpeg;
01170    }
01171 
01176    virtual void startMJPEGStream(void)
01177    {
01178       get(mStreamPath,false);
01179       mStreamHandler.start();
01180    }
01181 
01186    virtual void stopMJPEGStream(void)
01187    {
01188       mStreamHandler.cancel();
01189       mStreamHandler.waitfor();
01190       mClient.close();
01191    }
01192 
01193 
01194 
01195 protected:
01196    virtual void sendCommand(void)
01197    {
01198       std::cout << ViscaToString(mCmd) << std::endl;
01199       post(mSite,"VISCA",ViscaToString(mCmd),true);
01200    }
01201 
01202    MJPEGStream mStreamHandler;
01203 
01204 private:
01205    std::string mSite;
01206    std::string mImgPath;
01207    std::string mStreamPath;
01208 
01209 };
01210 
01211 }
01212 
01213 #endif

Generated on Thu Nov 30 00:34:19 2006 for PRIP by  doxygen 1.4.7