CVD 0.8
cvd/Linux/v4lbuffer.h
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