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
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
00633
00634
00635
00636
00637
00638
00639
00640
00641
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