00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef CVD_V4LBUFFER_H
00023 #define CVD_V4LBUFFER_H
00024
00025 #include <cvd/config.h>
00026
00027 #include <vector>
00028
00029 #ifdef CVD_INTERNAL_HAVE_STRANGE_V4L2
00030 #include <videodevx/videodev.h>
00031 #else
00032 #include <linux/videodev.h>
00033 #endif
00034
00035
00036
00037 #include <cvd/videobuffer.h>
00038 #include <cvd/byte.h>
00039 #include <cvd/rgb.h>
00040 #include <cvd/rgb8.h>
00041 #include <cvd/timer.h>
00042 #include <cvd/colourspaces.h>
00043 #include <fcntl.h>
00044
00045 namespace CVD {
00046
00047 namespace Exceptions
00048 {
00050 namespace V4LBuffer
00051 {
00053 struct All: public CVD::Exceptions::VideoBuffer::All
00054 {
00055 };
00058 struct DeviceOpen: public All {DeviceOpen(std::string dev);
00059 };
00062 struct DeviceSetup: public All {DeviceSetup(std::string dev, std::string action);
00063 };
00066 struct PutFrame: public All {PutFrame(std::string dev, std::string msg);
00067 };
00070 struct GetFrame: public All {GetFrame(std::string dev, std::string msg);
00071 };
00072 }
00073 }
00074
00075 namespace V4L
00076 {
00077 #ifndef DOXYGEN_IGNORE_INTERNAL
00078 template<class C> struct format;
00079
00080 template<> struct format<byte>
00081 {
00082 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_GREY;
00083 static const unsigned int v4l1_palette = VIDEO_PALETTE_GREY;
00084 };
00085
00086 #ifdef V4L2_PIX_FMT_SBGGR8
00087 template<> struct format<bayer_grbg>
00088 {
00089 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_SBGGR8;
00090 static const unsigned int v4l1_palette = VIDEO_PALETTE_RAW;
00091 };
00092 template<> struct format<bayer_bggr>
00093 {
00094 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_SBGGR8;
00095 static const unsigned int v4l1_palette = VIDEO_PALETTE_RAW;
00096 };
00097 #endif
00098
00099 template<> struct format<yuv422>
00100 {
00101 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_YUYV;
00102 static const unsigned int v4l1_palette = VIDEO_PALETTE_YUV422;
00103 };
00104
00105 template<> struct format<vuy422>
00106 {
00107 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_UYVY;
00108 static const unsigned int v4l1_palette = VIDEO_PALETTE_UYVY;
00109 };
00110
00111 template<> struct format<yuv420p>
00112 {
00113 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_YUV420;
00114 static const unsigned int v4l1_palette = VIDEO_PALETTE_YUV420P;
00115 };
00116
00117 template<> struct format<Rgb<byte> >
00118 {
00119 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_RGB24;
00120 static const unsigned int v4l1_palette = VIDEO_PALETTE_RGB24;
00121 };
00122
00123 template<> struct format<Rgb8>
00124 {
00125 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_RGB32;
00126 static const unsigned int v4l1_palette = VIDEO_PALETTE_RGB32;
00127 };
00128 #endif
00129
00130 class RawV4LBuffer: public virtual RawVideoBuffer
00131 {
00132 public:
00133 struct Buffer {
00134 int id;
00135 unsigned char* data;
00136 double when;
00137 };
00138
00139 RawV4LBuffer(const std::string& dev, unsigned int fmt, ImageRef size, int input, bool fields, int frame_per_second, bool verbose);
00140 ImageRef getSize();
00141 Buffer getFrame();
00142 void releaseFrame(int id);
00143 double getRate();
00144 bool pendingFrame();
00145 virtual ~RawV4LBuffer();
00146
00147 int num_buffers()
00148 {
00149 return num_bufs;
00150 }
00151
00152 const std::string & device_name() const
00153 {
00154 return dev;
00155 }
00156
00157 private:
00158 int num_bufs;
00159 struct State;
00160 State* state;
00161 std::string dev;
00162 };
00163
00164 class V4L1Client;
00165
00166 };
00167
00168
00172 template <class T> class V4LBuffer : public VideoBuffer<T>, public V4L::RawV4LBuffer
00173 {
00174 public:
00175 V4LBuffer(const std::string & dev, ImageRef size, int input=-1, bool fields=false, int frames_per_second=0, bool verbose=0)
00176 :VideoBuffer<T>(VideoBufferType::Flushable), RawV4LBuffer(dev, V4L::format<T>::v4l2_fmt, size, input, fields, frames_per_second, verbose)
00177 {
00178 }
00179
00180 virtual ImageRef size()
00181 {
00182 return getSize();
00183 }
00184
00185
00186 virtual VideoFrame<T> * get_frame() {
00187 V4L::RawV4LBuffer::Buffer buffer = getFrame();
00188 return new V4LFrame(buffer.id, buffer.when, buffer.data, getSize());
00189 }
00190
00191 virtual void put_frame(VideoFrame<T>* f) {
00192 V4LFrame* vf = dynamic_cast<V4LFrame*>(f);
00193 if (vf == 0)
00194 throw Exceptions::V4LBuffer::PutFrame(device_name(), "Invalid VideoFrame");
00195 int id = vf->id;
00196 delete vf;
00197
00198 releaseFrame(id);
00199 }
00200
00201 virtual bool frame_pending()
00202 {
00203 return pendingFrame();
00204 }
00205
00206 virtual double frame_rate()
00207 {
00208 return getRate();
00209 }
00210
00211 int num_buffers()
00212 {
00213 return num_buffers();
00214 }
00215
00216
00217 private:
00218
00219 struct V4LFrame : public VideoFrame<T> {
00220 V4LFrame(int i, double t, void* data, ImageRef size)
00221 :VideoFrame<T>(t,reinterpret_cast<T*>(data),size), id(i)
00222 {}
00223
00224 int id;
00225 friend class V4LBuffer<T>;
00226 };
00227
00228 V4LBuffer( V4LBuffer& copyof ) {}
00229 void operator=( V4LBuffer& copyof ) {}
00230
00231 };
00232
00233 };
00234 #endif