cvd/videosource.h

00001 #ifndef VIDEOSOURCE_H
00002 #define VIDEOSOURCE_H
00003 
00004 #include <iostream>
00005 #include <sstream>
00006 #include <string>
00007 #include <vector>
00008 #include <cstdlib>
00009 
00010 #include <cvd/config.h>
00011 
00012 #include <cvd/readaheadvideobuffer.h>
00013 #include <cvd/colourspaces.h>
00014 
00015 #include <cvd/diskbuffer2.h>
00016 #include <cvd/serverpushjpegbuffer.h>
00017 
00018 #if CVD_HAVE_FFMPEG
00019 #include <cvd/videofilebuffer.h>
00020 #endif
00021 
00022 #if CVD_INTERNAL_HAVE_V4LBUFFER
00023 #include <cvd/Linux/v4lbuffer.h>
00024 #endif
00025 
00026 #if CVD_HAVE_V4L1BUFFER
00027 #include <cvd/Linux/v4l1buffer.h>
00028 #endif
00029 
00030 #if CVD_HAVE_DVBUFFER
00031 #include <cvd/Linux/dvbuffer.h>
00032 #endif
00033 
00034 #if CVD_HAVE_QTBUFFER
00035 #include <cvd/OSX/qtbuffer.h>
00036 #endif
00037 
00038 namespace CVD {
00039     struct ParseException : public Exceptions::All
00040     {
00041     ParseException(const std::string& what_) { what = what_; }
00042     };
00043     
00044     struct VideoSourceException : public Exceptions::All
00045     {
00046     VideoSourceException(const std::string& what_) { what = what_; }
00047     };
00048 
00049     struct VideoSource 
00050     {
00051     std::string protocol;
00052     std::string identifier;
00053     typedef std::vector<std::pair<std::string,std::string> > option_list;
00054     option_list options;
00055     };
00056 
00057     std::ostream& operator<<(std::ostream& out, const VideoSource& vs);
00058 
00059     void parse(std::istream& in, VideoSource& vs);
00060 
00061     template <class T> VideoBuffer<T>* makeJPEGStream(const std::string& filename)
00062     {
00063         using std::auto_ptr;
00064     using std::ifstream;
00065 
00066         auto_ptr<ifstream> stream(new ifstream(filename.c_str()));
00067     
00068     ServerPushJpegBuffer<T>* b = new ServerPushJpegBuffer<T>(*stream.get());
00069     
00070     auto_ptr<VideoBufferData> h(new VideoBufferDataAuto<ifstream>(stream.release()));
00071 
00072     b->extra_data = h;
00073     return b;
00074     }
00075 
00076     template <> inline VideoBuffer<vuy422> * makeJPEGStream(const std::string&)
00077     {
00078     throw VideoSourceException("DiskBuffer2 cannot handle type vuy422");
00079     }
00080 
00081     template <> inline VideoBuffer<yuv422> * makeJPEGStream(const std::string&)
00082     {
00083     throw VideoSourceException("DiskBuffer2 cannot handle type yuv422");
00084     }
00085     void get_jpegstream_options(const VideoSource& vs, int& fps);
00086 
00087 
00088     
00089 #ifdef CVD_HAVE_GLOB
00090     template <class T> VideoBuffer<T>* makeDiskBuffer2(const std::vector<std::string>& files, double fps, VideoBufferFlags::OnEndOfBuffer eob)
00091     {
00092     return new DiskBuffer2<T>(files, fps, eob);    
00093     }
00094     template <> inline VideoBuffer<vuy422> * makeDiskBuffer2(const std::vector<std::string>& , double , VideoBufferFlags::OnEndOfBuffer )
00095     {
00096     throw VideoSourceException("DiskBuffer2 cannot handle type vuy422");
00097     }
00098     template <> inline VideoBuffer<yuv422> * makeDiskBuffer2(const std::vector<std::string>& , double , VideoBufferFlags::OnEndOfBuffer )
00099     {
00100     throw VideoSourceException("DiskBuffer2 cannot handle type yuv422");
00101     }
00102 #endif
00103 
00104     void get_files_options(const VideoSource& vs, int& fps, int& ra_frames, VideoBufferFlags::OnEndOfBuffer& eob);
00105     
00106 #if CVD_HAVE_V4L1BUFFER
00107     template <class T> VideoBuffer<T>* makeV4L1Buffer(const std::string&, const ImageRef& )
00108     {
00109     throw VideoSourceException("V4L1Buffer cannot handle types other than byte, bayer, yuv422, Rgb<byte>");
00110     }
00111 
00112     template <> VideoBuffer<byte>* makeV4L1Buffer(const std::string& dev, const ImageRef& size);
00113     template <> VideoBuffer<bayer>* makeV4L1Buffer(const std::string& dev, const ImageRef& size);
00114     template <> VideoBuffer<yuv422>* makeV4L1Buffer(const std::string& dev, const ImageRef& size);
00115     template <> VideoBuffer<Rgb<byte> >* makeV4L1Buffer(const std::string& dev, const ImageRef& size);
00116 
00117     void get_v4l1_options(const VideoSource& vs, ImageRef& size);
00118 
00119 #endif
00120 
00121     
00122 #if CVD_INTERNAL_HAVE_V4LBUFFER
00123     template <class T> VideoBuffer<T>* makeV4LBuffer(const std::string& dev, const ImageRef& size, int input, bool interlaced, bool verbose)
00124     {
00125     throw VideoSourceException("V4LBuffer cannot handle types other than byte, bayer, yuv422, Rgb<byte>");
00126     }
00127 
00128     template <> VideoBuffer<byte>* makeV4LBuffer(const std::string& dev, const ImageRef& size, int input, bool interlaced, bool verbose);
00129     template <> VideoBuffer<bayer>* makeV4LBuffer(const std::string& dev, const ImageRef& size, int input, bool interlaced, bool verbose);
00130     template <> VideoBuffer<yuv422>* makeV4LBuffer(const std::string& dev, const ImageRef& size, int input, bool interlaced, bool verbose);
00131     template <> VideoBuffer<Rgb<byte> >* makeV4LBuffer(const std::string& dev, const ImageRef& size, int input, bool interlaced, bool verbose);
00132     template <> VideoBuffer<Rgb8>* makeV4LBuffer(const std::string& dev, const ImageRef& size, int input, bool interlaced, bool verbose);
00133 
00134     void get_v4l2_options(const VideoSource& vs, ImageRef& size, int& input, bool& interlaced, bool& verbose);
00135 
00136 #endif
00137 
00138 
00139 #if CVD_HAVE_FFMPEG    
00140     template <class T> VideoBuffer<T>* makeVideoFileBuffer(const std::string& , VideoBufferFlags::OnEndOfBuffer )
00141     {
00142     throw VideoSourceException("VideoFileBuffer cannot handle types other than byte, Rgb<byte>");
00143     }
00144     
00145     template <> VideoBuffer<byte>* makeVideoFileBuffer(const std::string& file, VideoBufferFlags::OnEndOfBuffer eob);
00146     template <> VideoBuffer<Rgb<byte> >* makeVideoFileBuffer(const std::string& file, VideoBufferFlags::OnEndOfBuffer eob);
00147 
00148     void get_file_options(const VideoSource& vs, int& ra_frames, VideoBufferFlags::OnEndOfBuffer& eob);
00149 
00150 #endif
00151 
00152 #if CVD_HAVE_DVBUFFER
00153     template <class T> VideoBuffer<T>* makeDVBuffer2(int , int , int , int , int )
00154     {
00155     throw VideoSourceException("DVBuffer2 cannot handle types other than byte, Rgb<byte>");
00156     }
00157     
00158     template <> VideoBuffer<byte>* makeDVBuffer2(int cam, int dmabufs, int bright, int exposure, int fps);
00159     template <> VideoBuffer<Rgb<byte> >* makeDVBuffer2(int cam, int dmabufs, int bright, int exposure, int fps);
00160 
00161     void get_dc1394_options(const VideoSource& vs, int& dma_bufs, int& bright, int& exposure, int& fps);
00162 
00163 #endif
00164 
00165 #if CVD_HAVE_QTBUFFER
00166     template <class T> VideoBuffer<T> * makeQTBuffer( const ImageRef & , int , bool )
00167     {
00168     throw VideoSourceException("QTBuffer cannot handle types other than vuy422");
00169     }
00170     template <> VideoBuffer<vuy422> * makeQTBuffer( const ImageRef & size, int input, bool showsettings);
00171     template <> VideoBuffer<yuv422> * makeQTBuffer( const ImageRef & size, int input, bool showsettings);
00172     
00173     void get_qt_options(const VideoSource & vs, ImageRef & size, bool & showsettings);
00174 #endif
00175 
00176     template <class T> VideoBuffer<T>* open_video_source(const VideoSource& vs)
00177     {
00178     using std::auto_ptr;
00179     if(vs.protocol == "jpegstream")
00180     {
00181         int ra_frames=0;
00182         get_jpegstream_options(vs, ra_frames);
00183 
00184         auto_ptr<VideoBuffer<T> > jpeg_buffer(makeJPEGStream<T>(vs.identifier));
00185 
00186         if(ra_frames == 0)
00187             return jpeg_buffer.release();
00188         else
00189         {
00190             auto_ptr<VideoBuffer<T> > b(new ReadAheadVideoBuffer<T>(*(jpeg_buffer.get()), ra_frames));
00191             auto_ptr<VideoBufferData> h(new VideoBufferDataAuto<VideoBuffer<T> >(jpeg_buffer.release()));
00192             b->extra_data = h;
00193             return b.release();
00194         }
00195     }
00196 #if CVD_HAVE_GLOB
00197     else if (vs.protocol == "files") {
00198         int fps, ra_frames=0;
00199         VideoBufferFlags::OnEndOfBuffer eob;
00200         get_files_options(vs, fps, ra_frames, eob);
00201         VideoBuffer<T>* vb = makeDiskBuffer2<T>(globlist(vs.identifier), fps, eob);
00202         if (ra_frames)
00203         vb = new ReadAheadVideoBuffer<T>(*vb, ra_frames);
00204         return vb;
00205     }
00206 #endif
00207 
00208 
00209 #if CVD_HAVE_V4L1BUFFER
00210     else if (vs.protocol == "v4l1") {
00211         ImageRef size;
00212         get_v4l1_options(vs, size);
00213         return makeV4L1Buffer<T>(vs.identifier, size);
00214     } 
00215 #endif
00216 #if CVD_INTERNAL_HAVE_V4LBUFFER
00217     else if (vs.protocol == "v4l2") {
00218         ImageRef size;
00219         int input;
00220         bool interlaced, verbose;
00221         get_v4l2_options(vs, size, input, interlaced, verbose);
00222         return makeV4LBuffer<T>(vs.identifier, size, input, interlaced, verbose);   
00223     } 
00224 #endif
00225 #if CVD_HAVE_DVBUFFER
00226     else if (vs.protocol == "dc1394") {
00227         int cam_no = atoi(vs.identifier.c_str());
00228         int dma_bufs, bright, exposure, fps;
00229         get_dc1394_options(vs, dma_bufs, bright, exposure, fps);
00230         return makeDVBuffer2<T>(cam_no, dma_bufs, bright, exposure, fps);
00231     } 
00232 #endif
00233 #if CVD_HAVE_FFMPEG
00234     else if (vs.protocol == "file") {
00235         int ra_frames = 0;
00236         VideoBufferFlags::OnEndOfBuffer eob;
00237         get_file_options(vs, ra_frames, eob);
00238         VideoBuffer<T>* vb = makeVideoFileBuffer<T>(vs.identifier, eob);
00239         if (ra_frames)
00240         vb = new ReadAheadVideoBuffer<T>(*vb, ra_frames);
00241         return vb;
00242     } 
00243 #endif
00244 #if CVD_HAVE_QTBUFFER
00245     else if (vs.protocol == "qt") {
00246         ImageRef size;
00247         bool showsettings;
00248         int input = atoi(vs.identifier.c_str());
00249         get_qt_options(vs, size, showsettings);
00250         return makeQTBuffer<T>(size, input, showsettings);
00251     }
00252 #endif
00253     else
00254         throw VideoSourceException("undefined video source protocol: '" + vs.protocol + "'\n\t valid protocols: "
00255                                    "jpegstream, "
00256 #if CVD_HAVE_FFMPEG
00257                        "file, "
00258 #endif
00259 #if CVD_INTERNAL_HAVE_V4LBUFFER
00260                        "v4l2, "
00261 #endif
00262 #if CVD_HAVE_V4L1BUFFER
00263                        "v4l1, "
00264 #endif
00265 #if CVD_HAVE_DVBUFFER
00266                        "dc1394, "
00267 #endif
00268 #if CVD_HAVE_QTBUFFER
00269                        "qt, "
00270 #endif
00271 #ifdef CVD_HAVE_GLOB
00272                        "files"
00273 #endif 
00274                        );
00275     }
00276 
00283     template <class T> VideoBuffer<T>* open_video_source(std::istream& in)
00284     {
00285     VideoSource vs;
00286     parse(in, vs);
00287     return open_video_source<T>(vs);
00288     }
00289 
00396     template <class T> VideoBuffer<T>* open_video_source(const std::string& src)
00397     {
00398     std::istringstream in(src);
00399     return open_video_source<T>(in);
00400     }    
00401 }
00402 
00403 #endif

Generated on Wed Feb 18 10:23:02 2009 for CVD by  doxygen 1.5.3