CVD 0.8
|
00001 /* 00002 This file is part of the CVD Library. 00003 00004 Copyright (C) 2005 The Authors 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Lesser General Public 00008 License as published by the Free Software Foundation; either 00009 version 2.1 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public 00017 License along with this library; if not, write to the Free Software 00018 Foundation, Inc., 00019 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 //-*- c++ -*- 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/videodev2.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 #ifndef VIDEO_PALETTE_GREY 00046 /* These are restored from videodev.h, removed in recent v4l2. */ 00047 #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ 00048 #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ 00049 #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ 00050 #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ 00051 #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ 00052 #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ 00053 #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ 00054 #define VIDEO_PALETTE_YUYV 8 00055 #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ 00056 #define VIDEO_PALETTE_YUV420 10 00057 #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ 00058 #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ 00059 #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ 00060 #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ 00061 #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ 00062 #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ 00063 #define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ 00064 #define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ 00065 #endif 00066 00067 namespace CVD { 00068 00069 namespace Exceptions 00070 { 00072 namespace V4LBuffer 00073 { 00075 struct All: public CVD::Exceptions::VideoBuffer::All 00076 { 00077 }; 00080 struct DeviceOpen: public All {DeviceOpen(std::string dev); 00081 }; 00082 00085 struct NoColourspace: public All{ NoColourspace(std::string dev, std::string space); 00086 }; 00087 00090 struct DeviceSetup: public All {DeviceSetup(std::string dev, std::string action); 00091 }; 00094 struct PutFrame: public All {PutFrame(std::string dev, std::string msg); 00095 }; 00098 struct GetFrame: public All {GetFrame(std::string dev, std::string msg); 00099 }; 00100 } 00101 } 00102 00103 namespace V4L 00104 { 00105 #ifndef DOXYGEN_IGNORE_INTERNAL 00106 template<class C> struct format; 00107 00108 template<> struct format<byte> 00109 { 00110 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_GREY; 00111 static const unsigned int v4l1_palette = VIDEO_PALETTE_GREY; 00112 }; 00113 00114 #ifdef V4L2_PIX_FMT_SBGGR8 00115 template<> struct format<bayer_grbg> 00116 { 00117 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_SBGGR8; 00118 static const unsigned int v4l1_palette = VIDEO_PALETTE_RAW; 00119 }; 00120 template<> struct format<bayer_bggr> 00121 { 00122 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_SBGGR8; 00123 static const unsigned int v4l1_palette = VIDEO_PALETTE_RAW; 00124 }; 00125 #endif 00126 00127 template<> struct format<yuv422> 00128 { 00129 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_YUYV; 00130 static const unsigned int v4l1_palette = VIDEO_PALETTE_YUV422; 00131 }; 00132 00133 template<> struct format<vuy422> 00134 { 00135 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_UYVY; 00136 static const unsigned int v4l1_palette = VIDEO_PALETTE_UYVY; 00137 }; 00138 00139 template<> struct format<yuv420p> 00140 { 00141 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_YUV420; 00142 static const unsigned int v4l1_palette = VIDEO_PALETTE_YUV420P; 00143 }; 00144 00145 template<> struct format<Rgb<byte> > 00146 { 00147 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_RGB24; 00148 static const unsigned int v4l1_palette = VIDEO_PALETTE_RGB24; 00149 }; 00150 00151 template<> struct format<Rgb8> 00152 { 00153 static const unsigned int v4l2_fmt = V4L2_PIX_FMT_RGB32; 00154 static const unsigned int v4l1_palette = VIDEO_PALETTE_RGB32; 00155 }; 00156 #endif 00157 00158 class RawV4LBuffer: public virtual RawVideoBuffer 00159 { 00160 public: 00161 struct Buffer { 00162 int id; 00163 unsigned char* data; 00164 double when; 00165 }; 00166 00167 RawV4LBuffer(const std::string& dev, unsigned int fmt, ImageRef size, int input, bool fields, int frame_per_second, bool verbose); 00168 ImageRef getSize(); 00169 Buffer getFrame(); 00170 void releaseFrame(int id); 00171 double getRate(); 00172 bool pendingFrame(); 00173 virtual ~RawV4LBuffer(); 00174 00175 int num_buffers() 00176 { 00177 return num_bufs; 00178 } 00179 00180 const std::string & device_name() const 00181 { 00182 return dev; 00183 } 00184 00185 private: 00186 int num_bufs; 00187 struct State; 00188 State* state; 00189 std::string dev; 00190 }; 00191 00192 class V4L1Client; 00193 00194 }; 00195 00196 00200 template <class T> class V4LBuffer : public VideoBuffer<T>, public V4L::RawV4LBuffer 00201 { 00202 public: 00203 V4LBuffer(const std::string & dev, ImageRef size, int input=-1, bool fields=false, int frames_per_second=0, bool verbose=0) 00204 :VideoBuffer<T>(VideoBufferType::Flushable), RawV4LBuffer(dev, V4L::format<T>::v4l2_fmt, size, input, fields, frames_per_second, verbose) 00205 { 00206 } 00207 00208 virtual ImageRef size() 00209 { 00210 return getSize(); 00211 } 00212 00213 00214 virtual VideoFrame<T> * get_frame() { 00215 V4L::RawV4LBuffer::Buffer buffer = getFrame(); 00216 return new V4LFrame(buffer.id, buffer.when, buffer.data, getSize()); 00217 } 00218 00219 virtual void put_frame(VideoFrame<T>* f) { 00220 V4LFrame* vf = dynamic_cast<V4LFrame*>(f); 00221 if (vf == 0) 00222 throw Exceptions::V4LBuffer::PutFrame(device_name(), "Invalid VideoFrame"); 00223 int id = vf->id; 00224 delete vf; 00225 00226 releaseFrame(id); 00227 } 00228 00229 virtual bool frame_pending() 00230 { 00231 return pendingFrame(); 00232 } 00233 00234 virtual double frame_rate() 00235 { 00236 return getRate(); 00237 } 00238 00239 int num_buffers() 00240 { 00241 return num_buffers(); 00242 } 00243 00244 00245 private: 00246 00247 struct V4LFrame : public VideoFrame<T> { 00248 V4LFrame(int i, double t, void* data, ImageRef size) 00249 :VideoFrame<T>(t,reinterpret_cast<T*>(data),size), id(i) 00250 {} 00251 00252 int id; 00253 friend class V4LBuffer<T>; 00254 }; 00255 00256 V4LBuffer( V4LBuffer& copyof ) {} 00257 void operator=( V4LBuffer& copyof ) {} 00258 00259 }; 00260 00261 }; 00262 #endif