V4Lgrabber.H

Go to the documentation of this file.
00001 /*!@file Devices/V4Lgrabber.H Definition and access functions for video4linux
00002   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/V4Lgrabber.H $
00036 // $Id: V4Lgrabber.H 10794 2009-02-08 06:21:09Z itti $
00037 //
00038 
00039 #ifndef V4LGRABBER_H_DEFINED
00040 #define V4LGRABBER_H_DEFINED
00041 
00042 #ifdef HAVE_LINUX_VIDEODEV_H
00043 
00044 // We need this in order for <linux/videodev.h> to be parsed
00045 // successfully (we could avoid this if we didn't have -ansi on the
00046 // command-line; not sure in fact why we have -ansi there in the first
00047 // place)
00048 #undef __STRICT_ANSI__
00049 
00050 #include "Component/ModelParam.H"
00051 #include "Image/Image.H"
00052 #include "Image/Pixels.H"
00053 #include "Transport/FrameIstream.H"
00054 #include "Util/SimTime.H"
00055 #include "Util/Types.H"
00056 #include "Video/VideoFormat.H"
00057 
00058 #include <linux/videodev.h>
00059 
00060 class VideoFrame;
00061 
00062 //! Definition and access functions for video4linux frame grabber
00063 /*! This class provides a trivial interface to Video4Linux frame
00064   grabbers.  All the low-level setup is done during construction. The
00065   user only needs to call readRGB() or readFrame() to capture an
00066   image. Shared memory and DMA directly from the grabber hardware into
00067   our memory is used if supported by the grabber and driver. This
00068   should work with any framegrabber that is supported by
00069   Video4Linux. We use Bt878-based boards.
00070 
00071   After each grab, the next grab is initiated, and will be ready 33ms
00072   later (or one frame later if not NTSC). If you call readFrame() again
00073   before 33ms have elapsed, it will block until the next frame is
00074   available. If you call it too late, you will have missed the latest
00075   frame, and readFrame() will block until the next frame is acquired.
00076 
00077   So a good strategy is to use readFrame() to not only grab but also
00078   to synchronize your code with the video rate (30 frames/s if NTSC).
00079   Typically, then, you would have a main loop that first grabs and
00080   then does various processing that is guaranteed to take less than
00081   33ms.  You do not need to insert any pause after that processing to
00082   obtain a stable framerate; just finish your main loop, and the next
00083   call to readFrame() (at the next iteration) will block until exactly
00084   one frame has passed since it was last called. See how this is done,
00085   for example, in pvisionTCP-master.C or test-grab.C  */
00086 
00087 class V4Lgrabber : public FrameIstream
00088 {
00089 public:
00090   //! Constructor
00091   V4Lgrabber(OptionManager& mgr,
00092              const std::string& descrName = "V4L Frame Grabber Driver",
00093              const std::string& tagName = "V4LFrameGrabber",
00094              const ParamFlag flags = USE_MY_VAL);
00095 
00096   //! Destructor
00097   virtual ~V4Lgrabber();
00098 
00099   /// Install a FrameListener
00100   /** We call the listener's onRawFrame() inside each readFrame(). */
00101   virtual void setListener(rutz::shared_ptr<FrameListener> listener);
00102 
00103   //! Get a streaming grab started
00104   /*! This will instruct the grabber to grab all of its possible
00105     buffers, one after the other. Typically you should call this just
00106     before you start reading frames. If the option
00107     --framegrabber-streaming=false is set, then this call is a (safe)
00108     no-op. */
00109   virtual void startStream();
00110 
00111   //! Return the specifications of the next frame to be returned
00112   virtual GenericFrameSpec peekFrameSpec();
00113 
00114   //! Get the inter-frame time that matches our video mode
00115   virtual SimTime getNaturalFrameTime() const;
00116 
00117   //! Get the next frame from the frame-grabber
00118   /*! Returns grabbed frame. This call will block until a frame is
00119       ready and has been grabbed.
00120 
00121       Beware that the integrity of the GenericFrame object may not
00122       last "very long"; basically, try to be finished using the
00123       GenericFrame object before you attempt to grab the next frame in
00124       the stream. If you need it for longer than that, then you should
00125       use GenericFrame::deepCopyOf() to make a copy of the frame that
00126       can be safely held indefinitely. */
00127   virtual GenericFrame readFrame();
00128 
00129 protected:
00130   //! Grab a raw VideoFrame
00131   /*! Don't call this directly; use readFrame() instead. */
00132   VideoFrame grabRaw();
00133 
00134   //! Grab a single VideoFrame
00135   /*! Don't call this directly; use readFrame() instead.
00136 
00137       This function will work better with single-shot grabs (as
00138       opposed to video) and USB cameras. */
00139   VideoFrame grabSingleRaw();
00140 
00141   //! get started
00142   virtual void start1();
00143 
00144   //! get stopped
00145   virtual void stop2();
00146 
00147 private:
00148   //! Set the camera parameters on the fly
00149   virtual void paramChanged(ModelParamBase* const param,
00150                             const bool valueChanged,
00151                             ParamClient::ChangeStatus* status);
00152 
00153   //! Auxiliary helper for startStream()
00154   void restartStream();
00155 
00156   //! device name of the /dev/ entry for the grabber device
00157   OModelParam<std::string> itsDevName;
00158 
00159   //! input channel to use
00160   OModelParam<int> itsChannel;
00161 
00162   //! width of grabbed frames
00163   OModelParam<Dims> itsDims;
00164 
00165   //! grab mode that the hardware should use
00166   /*! Grabbed frames will internally be converted to Image<
00167     PixRGB<byte> > whatever that mode is, but playing with it may
00168     influence image quality, maximum achievable framerate, and amounts
00169     of CPU doing those conversions to RGB. */
00170   OModelParam<VideoFormat> itsGrabMode;
00171 
00172   //! determines whether byte swapping is done during conversion to RGB
00173   OModelParam<bool> itsByteSwap;
00174 
00175   //! brightness - highly dependent on your driver
00176   OModelParam<int> itsBrightness;
00177 
00178   //! hue - highly dependent on your driver
00179   OModelParam<int> itsHue;
00180 
00181   //! color - highly dependent on your driver
00182   OModelParam<int> itsColour;
00183 
00184   //! contrast - highly dependent on your driver
00185   OModelParam<int> itsContrast;
00186 
00187   //! whiteness - highly dependent on your driver
00188   OModelParam<int> itsWhiteness;
00189 
00190   //! whether to operate in streaming or single-frame mode
00191   OModelParam<bool> itsStreamingMode;
00192 
00193   int itsFd;                //!< file descriptor for video device
00194   byte* itsMmapBuf;         //!< mmap'ed buffer with the video frames
00195   Image<byte> itsReadBuf;   //!< raw buffer for use with read() interface
00196   int itsTotalBufSize;      //!< size of the mmap'ed buffer
00197   int itsNumBufFrames;      //!< total number of frames in buf
00198   int itsCurrentFrame;      //!< current frame
00199   bool* itsGrabbing;        //!< which buffers have we told the hardware to grab?
00200 
00201   struct video_mmap itsVmmInfo;
00202 
00203   SimTime itsFrameTime;     //!< inter-frame time for our video mode
00204 
00205   rutz::shared_ptr<FrameListener> itsListener;
00206 
00207   bool itsStreamStarted;    //!< whether startStream() has been called
00208 };
00209 
00210 #endif // HAVE_LINUX_VIDEODEV_H
00211 
00212 #endif
00213 
00214 // ######################################################################
00215 /* So things look consistent in everyone's emacs... */
00216 /* Local Variables: */
00217 /* indent-tabs-mode: nil */
00218 /* End: */
Generated on Sun May 8 08:40:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3