v4l.cpp

00001 
00002 /***************************************************************************
00003  *  v4l.cpp - General Video4Linux access
00004  *
00005  *  Generated: Sat Jul  5 16:16:16 2008
00006  *  Copyright  2008  Tobias Kellner
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #include <cams/v4l.h>
00025 
00026 #include <cstdlib>
00027 #include <cstring>
00028 #include <fcntl.h>
00029 #include <sys/ioctl.h>
00030 
00031 #ifdef HAVE_V4L1_CAM
00032 #include <linux/videodev.h>
00033 #include <cams/v4l1.h>
00034 #endif
00035 
00036 #ifdef HAVE_V4L2_CAM
00037 #include <linux/videodev2.h>
00038 #include <cams/v4l2.h>
00039 #endif
00040 
00041 #include <fvutils/system/camargp.h>
00042 #include <core/exception.h>
00043 #include <core/exceptions/software.h>
00044 
00045 namespace firevision {
00046 #if 0 /* just to make Emacs auto-indent happy */
00047 }
00048 #endif
00049 
00050 /** @class V4LCamera <cams/v4l.h>
00051  * General Video4Linux camera implementation.
00052  * Maintains backwards compatibility.
00053  * Chooses on the fly whether v4l1 or v4l2 is needed for a given device.
00054  * @author Tobias Kellner
00055  */
00056 
00057 /** Constructor.
00058  * @param device_name device file name (e.g. /dev/video0)
00059  */
00060 V4LCamera::V4LCamera(const char *device_name)
00061 {
00062   _v4l_cam = NULL;
00063   _device_name = strdup(device_name);
00064 }
00065 
00066 
00067 /** Constructor.
00068  * Initialize camera with parameters from camera argument parser.
00069  * Supported arguments:
00070  * - device=DEV, device file, for example /dev/video0
00071  * @param cap camera argument parser
00072  */
00073 V4LCamera::V4LCamera(const CameraArgumentParser *cap)
00074 {
00075   _v4l_cam = NULL;
00076   if (cap->has("device")) _device_name = strdup(cap->get("device").c_str());
00077   else throw fawkes::MissingParameterException("Missing device for V4lCamera");
00078 }
00079 
00080 /** Destructor. */
00081 V4LCamera::~V4LCamera()
00082 {
00083   free(_device_name);
00084   if (_v4l_cam) delete _v4l_cam;
00085 }
00086 
00087 void
00088 V4LCamera::open()
00089 {
00090   if (_v4l_cam) delete _v4l_cam;
00091 
00092   int dev = ::open(_device_name, O_RDWR);
00093   if (dev < 0) throw fawkes::Exception("V4LCam: Could not open device");
00094 
00095 #ifdef HAVE_V4L1_CAM
00096   struct video_capability caps1;
00097 #endif
00098 #ifdef HAVE_V4L2_CAM
00099   struct v4l2_capability caps2;
00100 #endif
00101 
00102 #ifdef HAVE_V4L2_CAM
00103   if (ioctl(dev, VIDIOC_QUERYCAP, &caps2))
00104   {
00105 #endif
00106 #ifdef HAVE_V4L1_CAM
00107     if (ioctl(dev, VIDIOCGCAP, &caps1))
00108     {
00109 #endif
00110       throw fawkes::Exception("V4LCam: Device doesn't appear to be a v4l device");
00111 #ifdef HAVE_V4L1_CAM
00112     }
00113     _v4l_cam = new V4L1Camera(_device_name, dev);
00114 #endif
00115 #ifdef HAVE_V4L2_CAM
00116   }
00117   else
00118   {
00119     _v4l_cam = new V4L2Camera(_device_name, dev);
00120   }
00121 #endif
00122 }
00123 
00124 
00125 void
00126 V4LCamera::start()
00127 {
00128   if (!_v4l_cam) throw fawkes::Exception("V4LCam: Trying to start closed cam!");
00129 
00130   _v4l_cam->start();
00131 }
00132 
00133 void
00134 V4LCamera::stop()
00135 {
00136   if (!_v4l_cam) throw fawkes::Exception("V4LCam: Trying to stop closed cam!");
00137 
00138   _v4l_cam->stop();
00139 }
00140 
00141 void
00142 V4LCamera::close()
00143 {
00144   if (_v4l_cam) _v4l_cam->close();
00145 }
00146 
00147 void
00148 V4LCamera::flush()
00149 {
00150   if (_v4l_cam) _v4l_cam->flush();
00151 }
00152 
00153 void
00154 V4LCamera::capture()
00155 {
00156   if (_v4l_cam) _v4l_cam->capture();
00157 }
00158 
00159 void
00160 V4LCamera::print_info()
00161 {
00162   if (_v4l_cam) _v4l_cam->print_info();
00163 }
00164 
00165 bool
00166 V4LCamera::ready()
00167 {
00168   return (_v4l_cam ? _v4l_cam->ready() : false);
00169 }
00170 
00171 unsigned char*
00172 V4LCamera::buffer()
00173 {
00174   return (_v4l_cam ? _v4l_cam->buffer() : NULL);
00175 }
00176 
00177 unsigned int
00178 V4LCamera::buffer_size()
00179 {
00180   return (_v4l_cam ? _v4l_cam->buffer_size() : 0);
00181 }
00182 
00183 void
00184 V4LCamera::dispose_buffer()
00185 {
00186   if (_v4l_cam) _v4l_cam->dispose_buffer();
00187 }
00188 
00189 unsigned int
00190 V4LCamera::pixel_width()
00191 {
00192   if (!_v4l_cam) throw fawkes::Exception("V4LCam::pixel_width(): Camera not opened");
00193 
00194   return _v4l_cam->pixel_width();
00195 }
00196 
00197 unsigned int
00198 V4LCamera::pixel_height()
00199 {
00200   if (!_v4l_cam) throw fawkes::Exception("V4LCam::pixel_height(): Camera not opened");
00201 
00202   return _v4l_cam->pixel_height();
00203 }
00204 
00205 colorspace_t
00206 V4LCamera::colorspace()
00207 {
00208   return (_v4l_cam ? _v4l_cam->colorspace() : CS_UNKNOWN);
00209 }
00210 
00211 void
00212 V4LCamera::set_image_number(unsigned int n)
00213 {
00214   if (_v4l_cam) _v4l_cam->set_image_number(n);
00215 }
00216 
00217 } // end namespace firevision