V4L2grabber.H

Go to the documentation of this file.
00001 /*!@file Devices/V4L2grabber.H Definition and access functions for
00002   video4linux v2 grabber */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/V4L2grabber.H $
00036 // $Id: V4L2grabber.H 14046 2010-09-25 05:58:24Z itti $
00037 //
00038 
00039 #ifndef V4L2GRABBER_H_DEFINED
00040 #define V4L2GRABBER_H_DEFINED
00041 
00042 #ifdef HAVE_LINUX_VIDEODEV2_H
00043 
00044 #include <linux/videodev2.h>
00045 
00046 #include "Component/ModelParam.H"
00047 #include "Image/Image.H"
00048 #include "Image/Pixels.H"
00049 #include "Transport/FrameIstream.H"
00050 #include "Util/SimTime.H"
00051 #include "Util/Types.H"
00052 #include "Video/VideoFormat.H"
00053 
00054 class VideoFrame;
00055 
00056 //! Definition and access functions for video4linux2 frame grabber
00057 /*! This class provides a trivial interface to Video4Linux2 frame
00058   grabbers.  All the low-level setup is done during construction. The
00059   user only needs to call readRGB() or readFrame() to capture an
00060   image. Shared memory and DMA directly from the grabber hardware into
00061   our memory is used if supported by the grabber and driver. This
00062   should work with any framegrabber that is supported by
00063   Video4Linux. We use Bt878-based boards.
00064 
00065   After each grab, the next grab is initiated, and will be ready 33ms
00066   later (or one frame later if not NTSC). If you call readFrame() again
00067   before 33ms have elapsed, it will block until the next frame is
00068   available. If you call it too late, you will have missed the latest
00069   frame, and readFrame() will block until the next frame is acquired.
00070 
00071   So a good strategy is to use readFrame() to not only grab but also
00072   to synchronize your code with the video rate (30 frames/s if NTSC).
00073   Typically, then, you would have a main loop that first grabs and
00074   then does various processing that is guaranteed to take less than
00075   33ms.  You do not need to insert any pause after that processing to
00076   obtain a stable framerate; just finish your main loop, and the next
00077   call to readFrame() (at the next iteration) will block until exactly
00078   one frame has passed since it was last called. See how this is done,
00079   for example, in pvisionTCP-master.C or test-grab.C  */
00080 
00081 class V4L2grabber : public FrameIstream
00082 {
00083 public:
00084   //! Constructor
00085   V4L2grabber(OptionManager& mgr,
00086               const std::string& descrName = "V4L Frame Grabber Driver",
00087               const std::string& tagName = "V4LFrameGrabber",
00088               const ParamFlag flags = USE_MY_VAL);
00089 
00090   //! Destructor
00091   virtual ~V4L2grabber();
00092 
00093   /// Install a FrameListener
00094   /** We call the listener's onRawFrame() inside each readFrame(). */
00095   virtual void setListener(rutz::shared_ptr<FrameListener> listener);
00096 
00097   //! Get a streaming grab started
00098   /*! This will instruct the grabber to grab all of its possible
00099     buffers, one after the other. Typically you should call this just
00100     before you start reading frames. If the option
00101     --framegrabber-streaming=false is set, then this call is a (safe)
00102     no-op. */
00103   virtual void startStream();
00104 
00105   //! Return the specifications of the next frame to be returned
00106   virtual GenericFrameSpec peekFrameSpec();
00107 
00108   //! Get the inter-frame time that matches our video mode
00109   virtual SimTime getNaturalFrameTime() const;
00110 
00111   //! Get the next frame from the frame-grabber
00112   /*! Returns grabbed frame. This call will block until a frame is
00113       ready and has been grabbed.
00114 
00115       Beware that the integrity of the GenericFrame object may not
00116       last "very long"; basically, try to be finished using the
00117       GenericFrame object before you attempt to grab the next frame in
00118       the stream. If you need it for longer than that, then you should
00119       use GenericFrame::deepCopyOf() to make a copy of the frame that
00120       can be safely held indefinitely. */
00121   virtual GenericFrame readFrame();
00122 
00123 
00124 
00125 protected:
00126   //! Grab a raw VideoFrame
00127   /*! Don't call this directly; use readFrame() instead. */
00128   VideoFrame grabRaw();
00129 
00130   //! Grab a single VideoFrame
00131   /*! Don't call this directly; use readFrame() instead.
00132 
00133       This function will work better with single-shot grabs (as
00134       opposed to video) and USB cameras. */
00135   VideoFrame grabSingleRaw();
00136 
00137   //! get started
00138   virtual void start1();
00139 
00140   //! get stopped
00141   virtual void stop2();
00142 
00143 
00144 private:
00145   //! Set the camera parameters on the fly
00146   virtual void paramChanged(ModelParamBase* const param,
00147                             const bool valueChanged,
00148                             ParamClient::ChangeStatus* status);
00149 
00150   //! Auxiliary helper for startStream()
00151   void restartStream();
00152 
00153   //! device name of the /dev/ entry for the grabber device
00154   OModelParam<std::string> itsDevName;
00155 
00156   //! input channel to use
00157   OModelParam<int> itsChannel;
00158 
00159   //! width of grabbed frames
00160   OModelParam<Dims> itsDims;
00161 
00162   //! grab mode that the hardware should use
00163   /*! Grabbed frames will internally be converted to Image<
00164     PixRGB<byte> > whatever that mode is, but playing with it may
00165     influence image quality, maximum achievable framerate, and amounts
00166     of CPU doing those conversions to RGB. */
00167   OModelParam<VideoFormat> itsGrabMode;
00168 
00169   //! determines whether byte swapping is done during conversion to RGB
00170   OModelParam<bool> itsByteSwap;
00171 
00172   //! whether to operate in streaming or single-frame mode
00173   OModelParam<bool> itsStreamingMode;
00174 
00175   //! number of frame buffers kept internally
00176   OModelParam<int> itsNbuf;
00177 
00178   int itsFd;                //!< file descriptor for video device
00179   byte** itsMmapBuf;        //!< mmap'ed buffer with the video frames
00180   int *itsMmapBufSize;      //!< size in bytes of each mmap'ed buffer
00181   Image<byte> itsReadBuf;   //!< raw buffer for use with read() interface
00182   int itsCurrentFrame;      //!< current frame
00183   bool* itsGrabbing;        //!< which bufs have we told the hardware to grab?
00184 
00185   SimTime itsFrameTime;     //!< inter-frame time for our video mode
00186 
00187   rutz::shared_ptr<FrameListener> itsListener;
00188 
00189   bool itsStreamStarted;    //!< whether startStream() has been called
00190 
00191   // management of V4L2 controls:
00192   class V4L2grabberControlBase {
00193   public:
00194     V4L2grabberControlBase(const int id, const v4l2_ctrl_type typ) : cid(id), ctype(typ) { }
00195     virtual ~V4L2grabberControlBase() { }
00196 
00197     uint cid; // use V4L2_CTRL_ID2CLASS(id) to get the control class
00198     v4l2_ctrl_type ctype;
00199   };
00200 
00201   template <class T> class V4L2grabberControl : public V4L2grabberControlBase {
00202   public:
00203     V4L2grabberControl(const ModelOptionDef *opt, ParamClient *client, const T& initval,
00204                        const ParamFlag flags, const int id, const v4l2_ctrl_type typ) :
00205       V4L2grabberControlBase(id, typ), param(opt, client, initval, flags | ALLOW_ONLINE_CHANGES) { }
00206 
00207     virtual ~V4L2grabberControl() { }
00208 
00209     OModelParam<T> param;
00210   };
00211 
00212   std::vector<rutz::shared_ptr<V4L2grabberControlBase> > itsControls;
00213 
00214   bool itsCanMMap; // the device has mmap capability
00215   bool itsCanRW;   // the device has RW capability
00216 
00217 
00218   void openDevice();
00219   void closeDevice();
00220   void addControl(const struct v4l2_queryctrl & crtl);
00221 
00222   ParamFlag itsOptionFlags;
00223 };
00224 
00225 #endif // HAVE_LINUX_VIDEODEV2_H
00226 
00227 #endif
00228 
00229 // ######################################################################
00230 /* So things look consistent in everyone's emacs... */
00231 /* Local Variables: */
00232 /* indent-tabs-mode: nil */
00233 /* End: */
Generated on Sun May 8 08:04:45 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3