CVD 0.8
|
00001 #ifndef CVD_INC_SERVERPUSHJPEGBUFFER_H 00002 #define CVD_INC_SERVERPUSHJPEGBUFFER_H 00003 #include <cvd/localvideobuffer.h> 00004 #include <cvd/timer.h> 00005 #include <cvd/serverpushjpegframe.h> 00006 #include <iostream> 00007 00008 namespace CVD 00009 { 00010 00036 template<class C> class ServerPushJpegBuffer: public LocalVideoBuffer<C> 00037 { 00038 public: 00045 ServerPushJpegBuffer<C>(std::istream& i, bool warnings_=0, int eat_frames=0) 00046 :LocalVideoBuffer<C>(VideoBufferType::Live),is(i),warnings(warnings_) 00047 { 00048 std::string tmp; 00049 //Eat the first 10 frames because the camera sometimes takes a while to 00050 //crank out ones of the specified size 00051 00052 for(int junk=0; junk< eat_frames; junk++) 00053 gimme_an_image(tmp); 00054 00055 00056 //Eat the first frame just to get the size 00057 Image<C> c = gimme_an_image(tmp); 00058 s = c.size(); 00059 } 00060 00061 virtual ImageRef size() 00062 { 00063 return s; 00064 } 00065 00066 LocalVideoFrame<C>* get_frame() 00067 { 00068 Image<C> c; 00069 std::string data; 00070 00071 loop: 00072 c = gimme_an_image(data); 00073 00074 if(c.size() != s) 00075 { 00076 if(warnings) 00077 std::cerr << "ServerPushJpegBuffer: video frame is " << c.size() << " not " << s << std::endl; 00078 goto loop; 00079 } 00080 00081 return new ServerPushJpegFrame<C>(get_time_of_day(), c, data); 00082 } 00083 00084 void put_frame(VideoFrame<C>* f) 00085 { 00086 LocalVideoFrame<C>* g = dynamic_cast<LocalVideoFrame<C>*>(f); 00087 00088 if(g == NULL) 00089 throw CVD::Exceptions::VideoBuffer::BadPutFrame(); 00090 else 00091 delete g; 00092 } 00093 00094 bool frame_pending() 00095 { 00096 return 1; 00097 } 00098 00099 void seek_to(double){}; 00100 00102 double frame_rate() 00103 { 00104 return 30; 00105 } 00106 00107 private: 00108 std::istream& is; 00109 ImageRef s; 00110 bool warnings; 00111 00112 Image<C> gimme_an_image(std::string& data) 00113 { 00114 00115 std::string line; 00116 00117 int length; 00118 getline(is, line); //Get --ImageSeparator 00119 getline(is, line); //Get Content-Type: 00120 is >> line; //Get Content-Length: 00121 is >> length; //Get the actual content length 00122 getline(is, line); //Eat the rest of the line 00123 getline(is, line); //Get the blank line 00124 00125 data.resize(length); 00126 is.read(&data[0], length); 00127 00128 std::istringstream ss(data); 00129 00130 Image<C> c = img_load(ss); 00131 00132 is.get(); //Eat the \r\n after the JPEG 00133 is.get(); 00134 00135 return c; 00136 } 00137 }; 00138 00139 } 00140 #endif