camera.cpp
Go to the documentation of this file.
00001 #include <cstdio>
00002 #include <iostream>
00003 #include <iomanip>
00004 #include <unistd.h>
00005 #include <sys/mman.h>
00006 
00007 #include "camera.h"
00008 
00009 /* raw camera member functions */
00010 v4l_capture::v4l_capture()
00011   : dev_name(""), fd(-1), width(640), height(480),
00012     buffers(NULL), n_buffers(0)
00013 {};
00014 
00015 v4l_capture::~v4l_capture()
00016 {
00017   stop_capturing();
00018   uninit_device();
00019   close_device();
00020 };
00021 
00022 int
00023 v4l_capture::init(size_t _width, size_t _height, unsigned int devId)
00024 {
00025   width = _width;
00026   height = _height;
00027   if (!init_all(width, height, devId)) return -1;
00028   frame = cv::Mat(height, width, CV_8UC3);
00029   return 0;
00030 }
00031 
00032 uchar *
00033 v4l_capture::capture ()
00034 {
00035   write_img(frame.data);
00036   return frame.data;
00037 }
00038 
00039 
00040 int v4l_capture::getWidth ()
00041 {
00042     return width;
00043 }
00044 
00045 int v4l_capture::getHeight ()
00046 {
00047     return height;
00048 }
00049 
00050 bool v4l_capture::init_all(size_t _width, size_t _height, unsigned int _devId)
00051 {
00052   width = _width;
00053   height = _height;
00054   std::ostringstream oss("");
00055   oss << "/dev/video" << _devId;
00056   dev_name = oss.str();
00057   if (!open_device()) return false;
00058   init_device();
00059   if (!start_capturing()) return false;
00060   return true;
00061 }
00062 
00063 bool v4l_capture::open_device(void)
00064 {
00065   fprintf(stderr, "Opening device '%s'\n", dev_name.c_str());
00066   fd = open(dev_name.c_str(), O_RDWR, 0);
00067 
00068   if (fd == -1) {
00069     fprintf(stderr, "Cannot open '%s': %d, %s\n",
00070             dev_name.c_str(), errno, strerror(errno));
00071     return false;
00072   }
00073   return true;
00074 }
00075 
00076 void v4l_capture::close_device(void)
00077 {
00078   if (close(fd) == -1) {
00079     perror("close");
00080     exit(EXIT_FAILURE);
00081   }
00082   fd = -1;
00083 }
00084 
00085 void v4l_capture::write_img(uchar* ret)
00086 {
00087   read_frame();
00088 
00089   for (int i = 0; i < width * height; i += 2) {
00090     int y, r, g, b;
00091     int u, v;
00092     y = ((unsigned char *) buffers[0].start)[i * 2];
00093     u = ((unsigned char *) buffers[0].start)[i * 2 + 1] - 128;
00094     v = ((unsigned char *) buffers[0].start)[i * 2 + 3] - 128;
00095 
00096     r = y + 1.40200 * v;
00097     g = y - 0.71414 * v - 0.34414 * u;
00098     b = y + 1.77200 * u;
00099     ret[i * 3 + 0] = (unsigned char) (std::min(std::max(r, 0), 255));
00100     ret[i * 3 + 1] = (unsigned char) (std::min(std::max(g, 0), 255));
00101     ret[i * 3 + 2] = (unsigned char) (std::min(std::max(b, 0), 255));
00102 
00103     y = ((unsigned char *) buffers[0].start)[(i + 1) * 2];
00104 
00105     r = y + 1.40200 * v;
00106     g = y - 0.71414 * v - 0.34414 * u;
00107     b = y + 1.77200 * u;
00108     ret[(i + 1) * 3 + 0] = (unsigned char) (std::min(std::max(r, 0), 255));
00109     ret[(i + 1) * 3 + 1] = (unsigned char) (std::min(std::max(g, 0), 255));
00110     ret[(i + 1) * 3 + 2] = (unsigned char) (std::min(std::max(b, 0), 255));
00111   }
00112 }
00113 
00114 void v4l_capture::read_frame(void)
00115 {
00116   struct v4l2_buffer buf;
00117 
00118   memset (&(buf), 0, sizeof (buf));
00119 
00120   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00121   buf.memory = V4L2_MEMORY_MMAP;
00122 
00123   if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
00124     perror("VIDIOC_DQBUF");
00125     exit(EXIT_FAILURE);
00126   }
00127   assert(buf.index < n_buffers);
00128 
00129   if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
00130     perror("VIDIOC_QBUF");
00131     exit(EXIT_FAILURE);
00132   }
00133 }
00134 
00135 void v4l_capture::init_mmap(void)
00136 {
00137   struct v4l2_requestbuffers req;
00138 
00139   memset (&(req), 0, sizeof (req));
00140 
00141   req.count = 4;
00142   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00143   req.memory = V4L2_MEMORY_MMAP;
00144 
00145   if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
00146     perror("VIDIOC_REQBUFS");
00147     exit(EXIT_FAILURE);
00148   }
00149 
00150   if (req.count < 2) {
00151     fprintf(stderr, "Insufficient buffer memory on %s\n", dev_name.c_str());
00152     exit(EXIT_FAILURE);
00153   }
00154 
00155   buffers = (buffer*)calloc(req.count, sizeof(*buffers));
00156 
00157   if (!buffers) {
00158     fprintf(stderr, "Out of memory\n");
00159     exit(EXIT_FAILURE);
00160   }
00161 
00162   for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
00163     struct v4l2_buffer buf;
00164 
00165     memset (&(buf), 0, sizeof (buf));
00166 
00167     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00168     buf.memory = V4L2_MEMORY_MMAP;
00169     buf.index = n_buffers;
00170 
00171     if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
00172       perror("VIDIOC_QUERYBUF");
00173       exit(EXIT_FAILURE);
00174     }
00175 
00176     buffers[n_buffers].length = buf.length;
00177     buffers[n_buffers].start = mmap(NULL /* start anywhere */ ,
00178                                     buf.length, PROT_READ | PROT_WRITE
00179                                     /* required */ ,
00180                                     MAP_SHARED /* recommended */ ,
00181                                     fd, buf.m.offset);
00182 
00183     if (buffers[n_buffers].start == MAP_FAILED) {
00184       perror("mmap");
00185       exit(EXIT_FAILURE);
00186     }
00187   }
00188 }
00189 
00190 void v4l_capture::uninit_mmap(void)
00191 {
00192   unsigned int i;
00193 
00194   for (i = 0; i < n_buffers; ++i) {
00195     if (munmap(buffers[i].start, buffers[i].length) == -1) {
00196       perror("munmap");
00197       exit(EXIT_FAILURE);
00198     }
00199   }
00200 }
00201 
00202 void v4l_capture::init_device(void)
00203 {
00204   struct v4l2_capability cap;
00205   struct v4l2_format fmt;
00206 
00207   if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
00208     if (EINVAL == errno) {
00209       fprintf(stderr, "%s is no V4L2 device\n", dev_name.c_str());
00210     }
00211     perror("VIDIOC_QUERYCAP");
00212     exit(EXIT_FAILURE);
00213   }
00214 
00215   fprintf(stderr, "video capabilities\n");
00216   fprintf(stderr, "cap.driver        =  %s\n", cap.driver);
00217   fprintf(stderr, "cap.card          =  %s\n", cap.card);
00218   fprintf(stderr, "cap.buf_info      =  %s\n", cap.bus_info);
00219   fprintf(stderr, "cap.version       =  %d\n", cap.version);
00220   fprintf(stderr, "cap.capabilities  =  0x%08x ", cap.capabilities);
00221   if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
00222     fprintf(stderr, " VIDEO_CAPTURE");
00223   if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
00224     fprintf(stderr, " VIDEO_OUTPUT");
00225   if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
00226     fprintf(stderr, " VIDEO_OVERLAY");
00227   if (cap.capabilities & V4L2_CAP_VBI_CAPTURE)
00228     fprintf(stderr, " VBI_CAPTURE");
00229   if (cap.capabilities & V4L2_CAP_VBI_OUTPUT)
00230     fprintf(stderr, " VBI_OUTPUT");
00231 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
00232   if (cap.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE)
00233     fprintf(stderr, " SLICED_VBI_CAPTURE");
00234 #endif
00235 #ifdef V4L2_CAP_SLICED_VBI_OUTPUT
00236   if (cap.capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
00237     fprintf(stderr, " VBI_SLICED_OUTPUT");
00238 #endif
00239   if (cap.capabilities & V4L2_CAP_RDS_CAPTURE)
00240     fprintf(stderr, " RDS_CAPTURE");
00241 #if V4L2_CAP_VIDEO_OUTPUT_OVERLAY
00242   if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
00243     fprintf(stderr, " VIDEO_OUTPUT_OVERLAY");
00244 #endif
00245   if (cap.capabilities & V4L2_CAP_TUNER)
00246     fprintf(stderr, " TUNER");
00247     if (cap.capabilities & V4L2_CAP_AUDIO)
00248         fprintf(stderr, " AUDIO");
00249     if (cap.capabilities & V4L2_CAP_RADIO)
00250         fprintf(stderr, " RADIO");
00251     if (cap.capabilities & V4L2_CAP_READWRITE)
00252         fprintf(stderr, " READWRITE");
00253     if (cap.capabilities & V4L2_CAP_ASYNCIO)
00254         fprintf(stderr, " ASYNCIO");
00255     if (cap.capabilities & V4L2_CAP_STREAMING)
00256         fprintf(stderr, " STREAMING");
00257     fprintf(stderr, "\n");
00258 
00259     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
00260       fprintf(stderr, "%s is no video capture device\n", dev_name.c_str());
00261         exit(EXIT_FAILURE);
00262     }
00263 
00264     memset (&(fmt), 0, sizeof (fmt));
00265 
00266     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00267     fmt.fmt.pix.width = width;
00268     fmt.fmt.pix.height = height;
00269     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
00270     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
00271 
00272     if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
00273         perror("VIDIOC_S_FMT");
00274         exit(EXIT_FAILURE);
00275     }
00276 
00277     init_mmap();
00278 }
00279 
00280 void v4l_capture::uninit_device(void)
00281 {
00282     uninit_mmap();
00283     free(buffers);
00284 }
00285 
00286 bool v4l_capture::start_capturing(void)
00287 {
00288     unsigned int i;
00289     enum v4l2_buf_type type;
00290 
00291     for (i = 0; i < n_buffers; ++i) {
00292         struct v4l2_buffer buf;
00293 
00294         memset (&(buf), 0, sizeof (buf));
00295 
00296         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00297         buf.memory = V4L2_MEMORY_MMAP;
00298         buf.index = i;
00299 
00300         if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
00301             perror("VIDIOC_QBUF");
00302             return false;
00303         }
00304     }
00305 
00306     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00307 
00308     if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
00309         perror("VIDIOC_STREAMON");
00310         return false;
00311     }
00312     return true;
00313 }
00314 
00315 void v4l_capture::stop_capturing(void)
00316 {
00317     enum v4l2_buf_type type;
00318 
00319     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00320 
00321     if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) {
00322         perror("VIDIOC_STREAMOFF");
00323         exit(EXIT_FAILURE);
00324     }
00325 
00326 }


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Wed Sep 6 2017 02:35:54