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   if (!write_img(frame.data)) return NULL;
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 bool v4l_capture::close_device(void)
00077 {
00078   if (close(fd) == -1) {
00079     perror("close");
00080     return false;
00081   }
00082   fd = -1;
00083   return true;
00084 }
00085 
00086 bool v4l_capture::write_img(uchar* ret)
00087 {
00088   if (!read_frame()) return false;
00089 
00090   for (int i = 0; i < width * height; i += 2) {
00091     int y, r, g, b;
00092     int u, v;
00093     y = ((unsigned char *) buffers[0].start)[i * 2];
00094     u = ((unsigned char *) buffers[0].start)[i * 2 + 1] - 128;
00095     v = ((unsigned char *) buffers[0].start)[i * 2 + 3] - 128;
00096 
00097     r = y + 1.40200 * v;
00098     g = y - 0.71414 * v - 0.34414 * u;
00099     b = y + 1.77200 * u;
00100     ret[i * 3 + 0] = (unsigned char) (std::min(std::max(r, 0), 255));
00101     ret[i * 3 + 1] = (unsigned char) (std::min(std::max(g, 0), 255));
00102     ret[i * 3 + 2] = (unsigned char) (std::min(std::max(b, 0), 255));
00103 
00104     y = ((unsigned char *) buffers[0].start)[(i + 1) * 2];
00105 
00106     r = y + 1.40200 * v;
00107     g = y - 0.71414 * v - 0.34414 * u;
00108     b = y + 1.77200 * u;
00109     ret[(i + 1) * 3 + 0] = (unsigned char) (std::min(std::max(r, 0), 255));
00110     ret[(i + 1) * 3 + 1] = (unsigned char) (std::min(std::max(g, 0), 255));
00111     ret[(i + 1) * 3 + 2] = (unsigned char) (std::min(std::max(b, 0), 255));
00112   }
00113 
00114   return true;
00115 }
00116 
00117 bool v4l_capture::read_frame(void)
00118 {
00119   struct v4l2_buffer buf;
00120 
00121   memset (&(buf), 0, sizeof (buf));
00122 
00123   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00124   buf.memory = V4L2_MEMORY_MMAP;
00125 
00126   if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
00127     perror("VIDIOC_DQBUF");
00128     return false;
00129   }
00130   assert(buf.index < n_buffers);
00131 
00132   if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
00133     perror("VIDIOC_QBUF");
00134     return false;
00135   }
00136 
00137   return true;
00138 }
00139 
00140 bool v4l_capture::init_mmap(void)
00141 {
00142   struct v4l2_requestbuffers req;
00143 
00144   memset (&(req), 0, sizeof (req));
00145 
00146   req.count = 4;
00147   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00148   req.memory = V4L2_MEMORY_MMAP;
00149 
00150   if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
00151     perror("VIDIOC_REQBUFS");
00152     return false;
00153   }
00154 
00155   if (req.count < 2) {
00156     fprintf(stderr, "Insufficient buffer memory on %s\n", dev_name.c_str());
00157     return false;
00158   }
00159 
00160   buffers = (buffer*)calloc(req.count, sizeof(*buffers));
00161 
00162   if (!buffers) {
00163     fprintf(stderr, "Out of memory\n");
00164     return false;
00165   }
00166 
00167   for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
00168     struct v4l2_buffer buf;
00169 
00170     memset (&(buf), 0, sizeof (buf));
00171 
00172     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00173     buf.memory = V4L2_MEMORY_MMAP;
00174     buf.index = n_buffers;
00175 
00176     if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
00177       perror("VIDIOC_QUERYBUF");
00178       return false;
00179     }
00180 
00181     buffers[n_buffers].length = buf.length;
00182     buffers[n_buffers].start = mmap(NULL /* start anywhere */ ,
00183                                     buf.length, PROT_READ | PROT_WRITE
00184                                     /* required */ ,
00185                                     MAP_SHARED /* recommended */ ,
00186                                     fd, buf.m.offset);
00187 
00188     if (buffers[n_buffers].start == MAP_FAILED) {
00189       perror("mmap");
00190       return false;
00191     }
00192   }
00193   return true;
00194 }
00195 
00196 bool v4l_capture::uninit_mmap(void)
00197 {
00198   unsigned int i;
00199 
00200   for (i = 0; i < n_buffers; ++i) {
00201     if (munmap(buffers[i].start, buffers[i].length) == -1) {
00202       perror("munmap");
00203       return false;
00204     }
00205   }
00206   return true;
00207 }
00208 
00209 bool v4l_capture::init_device(void)
00210 {
00211   struct v4l2_capability cap;
00212   struct v4l2_format fmt;
00213 
00214   if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
00215     if (EINVAL == errno) {
00216       fprintf(stderr, "%s is no V4L2 device\n", dev_name.c_str());
00217     }
00218     perror("VIDIOC_QUERYCAP");
00219     return false;
00220   }
00221 
00222   fprintf(stderr, "video capabilities\n");
00223   fprintf(stderr, "cap.driver        =  %s\n", cap.driver);
00224   fprintf(stderr, "cap.card          =  %s\n", cap.card);
00225   fprintf(stderr, "cap.buf_info      =  %s\n", cap.bus_info);
00226   fprintf(stderr, "cap.version       =  %d\n", cap.version);
00227   fprintf(stderr, "cap.capabilities  =  0x%08x ", cap.capabilities);
00228   if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
00229     fprintf(stderr, " VIDEO_CAPTURE");
00230   if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
00231     fprintf(stderr, " VIDEO_OUTPUT");
00232   if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
00233     fprintf(stderr, " VIDEO_OVERLAY");
00234   if (cap.capabilities & V4L2_CAP_VBI_CAPTURE)
00235     fprintf(stderr, " VBI_CAPTURE");
00236   if (cap.capabilities & V4L2_CAP_VBI_OUTPUT)
00237     fprintf(stderr, " VBI_OUTPUT");
00238 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
00239   if (cap.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE)
00240     fprintf(stderr, " SLICED_VBI_CAPTURE");
00241 #endif
00242 #ifdef V4L2_CAP_SLICED_VBI_OUTPUT
00243   if (cap.capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
00244     fprintf(stderr, " VBI_SLICED_OUTPUT");
00245 #endif
00246   if (cap.capabilities & V4L2_CAP_RDS_CAPTURE)
00247     fprintf(stderr, " RDS_CAPTURE");
00248 #if V4L2_CAP_VIDEO_OUTPUT_OVERLAY
00249   if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
00250     fprintf(stderr, " VIDEO_OUTPUT_OVERLAY");
00251 #endif
00252   if (cap.capabilities & V4L2_CAP_TUNER)
00253     fprintf(stderr, " TUNER");
00254     if (cap.capabilities & V4L2_CAP_AUDIO)
00255         fprintf(stderr, " AUDIO");
00256     if (cap.capabilities & V4L2_CAP_RADIO)
00257         fprintf(stderr, " RADIO");
00258     if (cap.capabilities & V4L2_CAP_READWRITE)
00259         fprintf(stderr, " READWRITE");
00260     if (cap.capabilities & V4L2_CAP_ASYNCIO)
00261         fprintf(stderr, " ASYNCIO");
00262     if (cap.capabilities & V4L2_CAP_STREAMING)
00263         fprintf(stderr, " STREAMING");
00264     fprintf(stderr, "\n");
00265 
00266     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
00267       fprintf(stderr, "%s is no video capture device\n", dev_name.c_str());
00268       return false;
00269     }
00270 
00271     memset (&(fmt), 0, sizeof (fmt));
00272 
00273     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00274     fmt.fmt.pix.width = width;
00275     fmt.fmt.pix.height = height;
00276     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
00277     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
00278 
00279     if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
00280         perror("VIDIOC_S_FMT");
00281         return false;
00282     }
00283 
00284     init_mmap();
00285     return true;
00286 }
00287 
00288 void v4l_capture::uninit_device(void)
00289 {
00290     uninit_mmap();
00291     free(buffers);
00292 }
00293 
00294 bool v4l_capture::start_capturing(void)
00295 {
00296     unsigned int i;
00297     enum v4l2_buf_type type;
00298 
00299     for (i = 0; i < n_buffers; ++i) {
00300         struct v4l2_buffer buf;
00301 
00302         memset (&(buf), 0, sizeof (buf));
00303 
00304         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00305         buf.memory = V4L2_MEMORY_MMAP;
00306         buf.index = i;
00307 
00308         if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
00309             perror("VIDIOC_QBUF");
00310             return false;
00311         }
00312     }
00313 
00314     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00315 
00316     if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
00317         perror("VIDIOC_STREAMON");
00318         return false;
00319     }
00320     return true;
00321 }
00322 
00323 bool v4l_capture::stop_capturing(void)
00324 {
00325     enum v4l2_buf_type type;
00326 
00327     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00328 
00329     if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) {
00330         perror("VIDIOC_STREAMOFF");
00331         return false;
00332     }
00333     return true;
00334 }


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Wed May 15 2019 05:02:17