camera.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <iostream>
3 #include <iomanip>
4 #include <unistd.h>
5 #include <sys/mman.h>
6 
7 #include "camera.h"
8 
9 /* raw camera member functions */
11  : dev_name(""), fd(-1), width(640), height(480),
12  buffers(NULL), n_buffers(0)
13 {};
14 
16 {
18  uninit_device();
19  close_device();
20 };
21 
22 int
23 v4l_capture::init(size_t _width, size_t _height, unsigned int devId)
24 {
25  width = _width;
26  height = _height;
27  if (!init_all(width, height, devId)) return -1;
28  frame = cv::Mat(height, width, CV_8UC3);
29  return 0;
30 }
31 
32 uchar *
34 {
35  if (!write_img(frame.data)) return NULL;
36  return frame.data;
37 }
38 
39 
41 {
42  return width;
43 }
44 
46 {
47  return height;
48 }
49 
50 bool v4l_capture::init_all(size_t _width, size_t _height, unsigned int _devId)
51 {
52  width = _width;
53  height = _height;
54  std::ostringstream oss("");
55  oss << "/dev/video" << _devId;
56  dev_name = oss.str();
57  if (!open_device()) return false;
58  init_device();
59  if (!start_capturing()) return false;
60  return true;
61 }
62 
64 {
65  fprintf(stderr, "Opening device '%s'\n", dev_name.c_str());
66  fd = open(dev_name.c_str(), O_RDWR, 0);
67 
68  if (fd == -1) {
69  fprintf(stderr, "Cannot open '%s': %d, %s\n",
70  dev_name.c_str(), errno, strerror(errno));
71  return false;
72  }
73  return true;
74 }
75 
77 {
78  if (close(fd) == -1) {
79  perror("close");
80  return false;
81  }
82  fd = -1;
83  return true;
84 }
85 
86 bool v4l_capture::write_img(uchar* ret)
87 {
88  if (!read_frame()) return false;
89 
90  for (int i = 0; i < width * height; i += 2) {
91  int y, r, g, b;
92  int u, v;
93  y = ((unsigned char *) buffers[0].start)[i * 2];
94  u = ((unsigned char *) buffers[0].start)[i * 2 + 1] - 128;
95  v = ((unsigned char *) buffers[0].start)[i * 2 + 3] - 128;
96 
97  r = y + 1.40200 * v;
98  g = y - 0.71414 * v - 0.34414 * u;
99  b = y + 1.77200 * u;
100  ret[i * 3 + 0] = (unsigned char) (std::min(std::max(r, 0), 255));
101  ret[i * 3 + 1] = (unsigned char) (std::min(std::max(g, 0), 255));
102  ret[i * 3 + 2] = (unsigned char) (std::min(std::max(b, 0), 255));
103 
104  y = ((unsigned char *) buffers[0].start)[(i + 1) * 2];
105 
106  r = y + 1.40200 * v;
107  g = y - 0.71414 * v - 0.34414 * u;
108  b = y + 1.77200 * u;
109  ret[(i + 1) * 3 + 0] = (unsigned char) (std::min(std::max(r, 0), 255));
110  ret[(i + 1) * 3 + 1] = (unsigned char) (std::min(std::max(g, 0), 255));
111  ret[(i + 1) * 3 + 2] = (unsigned char) (std::min(std::max(b, 0), 255));
112  }
113 
114  return true;
115 }
116 
118 {
119  struct v4l2_buffer buf;
120 
121  memset (&(buf), 0, sizeof (buf));
122 
123  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
124  buf.memory = V4L2_MEMORY_MMAP;
125 
126  if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
127  perror("VIDIOC_DQBUF");
128  return false;
129  }
130  assert(buf.index < n_buffers);
131 
132  if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
133  perror("VIDIOC_QBUF");
134  return false;
135  }
136 
137  return true;
138 }
139 
141 {
142  struct v4l2_requestbuffers req;
143 
144  memset (&(req), 0, sizeof (req));
145 
146  req.count = 4;
147  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
148  req.memory = V4L2_MEMORY_MMAP;
149 
150  if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
151  perror("VIDIOC_REQBUFS");
152  return false;
153  }
154 
155  if (req.count < 2) {
156  fprintf(stderr, "Insufficient buffer memory on %s\n", dev_name.c_str());
157  return false;
158  }
159 
160  buffers = (buffer*)calloc(req.count, sizeof(*buffers));
161 
162  if (!buffers) {
163  fprintf(stderr, "Out of memory\n");
164  return false;
165  }
166 
167  for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
168  struct v4l2_buffer buf;
169 
170  memset (&(buf), 0, sizeof (buf));
171 
172  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
173  buf.memory = V4L2_MEMORY_MMAP;
174  buf.index = n_buffers;
175 
176  if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
177  perror("VIDIOC_QUERYBUF");
178  return false;
179  }
180 
181  buffers[n_buffers].length = buf.length;
182  buffers[n_buffers].start = mmap(NULL /* start anywhere */ ,
183  buf.length, PROT_READ | PROT_WRITE
184  /* required */ ,
185  MAP_SHARED /* recommended */ ,
186  fd, buf.m.offset);
187 
188  if (buffers[n_buffers].start == MAP_FAILED) {
189  perror("mmap");
190  return false;
191  }
192  }
193  return true;
194 }
195 
197 {
198  unsigned int i;
199 
200  for (i = 0; i < n_buffers; ++i) {
201  if (munmap(buffers[i].start, buffers[i].length) == -1) {
202  perror("munmap");
203  return false;
204  }
205  }
206  return true;
207 }
208 
210 {
211  struct v4l2_capability cap;
212  struct v4l2_format fmt;
213 
214  if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
215  if (EINVAL == errno) {
216  fprintf(stderr, "%s is no V4L2 device\n", dev_name.c_str());
217  }
218  perror("VIDIOC_QUERYCAP");
219  return false;
220  }
221 
222  fprintf(stderr, "video capabilities\n");
223  fprintf(stderr, "cap.driver = %s\n", cap.driver);
224  fprintf(stderr, "cap.card = %s\n", cap.card);
225  fprintf(stderr, "cap.buf_info = %s\n", cap.bus_info);
226  fprintf(stderr, "cap.version = %d\n", cap.version);
227  fprintf(stderr, "cap.capabilities = 0x%08x ", cap.capabilities);
228  if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
229  fprintf(stderr, " VIDEO_CAPTURE");
230  if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
231  fprintf(stderr, " VIDEO_OUTPUT");
232  if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
233  fprintf(stderr, " VIDEO_OVERLAY");
234  if (cap.capabilities & V4L2_CAP_VBI_CAPTURE)
235  fprintf(stderr, " VBI_CAPTURE");
236  if (cap.capabilities & V4L2_CAP_VBI_OUTPUT)
237  fprintf(stderr, " VBI_OUTPUT");
238 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
239  if (cap.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE)
240  fprintf(stderr, " SLICED_VBI_CAPTURE");
241 #endif
242 #ifdef V4L2_CAP_SLICED_VBI_OUTPUT
243  if (cap.capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
244  fprintf(stderr, " VBI_SLICED_OUTPUT");
245 #endif
246  if (cap.capabilities & V4L2_CAP_RDS_CAPTURE)
247  fprintf(stderr, " RDS_CAPTURE");
248 #if V4L2_CAP_VIDEO_OUTPUT_OVERLAY
249  if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
250  fprintf(stderr, " VIDEO_OUTPUT_OVERLAY");
251 #endif
252  if (cap.capabilities & V4L2_CAP_TUNER)
253  fprintf(stderr, " TUNER");
254  if (cap.capabilities & V4L2_CAP_AUDIO)
255  fprintf(stderr, " AUDIO");
256  if (cap.capabilities & V4L2_CAP_RADIO)
257  fprintf(stderr, " RADIO");
258  if (cap.capabilities & V4L2_CAP_READWRITE)
259  fprintf(stderr, " READWRITE");
260  if (cap.capabilities & V4L2_CAP_ASYNCIO)
261  fprintf(stderr, " ASYNCIO");
262  if (cap.capabilities & V4L2_CAP_STREAMING)
263  fprintf(stderr, " STREAMING");
264  fprintf(stderr, "\n");
265 
266  if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
267  fprintf(stderr, "%s is no video capture device\n", dev_name.c_str());
268  return false;
269  }
270 
271  memset (&(fmt), 0, sizeof (fmt));
272 
273  fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
274  fmt.fmt.pix.width = width;
275  fmt.fmt.pix.height = height;
276  fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
277  fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
278 
279  if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
280  perror("VIDIOC_S_FMT");
281  return false;
282  }
283 
284  init_mmap();
285  return true;
286 }
287 
289 {
290  uninit_mmap();
291  free(buffers);
292 }
293 
295 {
296  unsigned int i;
297  enum v4l2_buf_type type;
298 
299  for (i = 0; i < n_buffers; ++i) {
300  struct v4l2_buffer buf;
301 
302  memset (&(buf), 0, sizeof (buf));
303 
304  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
305  buf.memory = V4L2_MEMORY_MMAP;
306  buf.index = i;
307 
308  if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
309  perror("VIDIOC_QBUF");
310  return false;
311  }
312  }
313 
314  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
315 
316  if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
317  perror("VIDIOC_STREAMON");
318  return false;
319  }
320  return true;
321 }
322 
324 {
325  enum v4l2_buf_type type;
326 
327  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
328 
329  if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) {
330  perror("VIDIOC_STREAMOFF");
331  return false;
332  }
333  return true;
334 }
#define max(a, b)
bool uninit_mmap()
Definition: camera.cpp:196
buffer * buffers
Definition: camera.h:20
png_infop png_charp png_int_32 png_int_32 int * type
int getHeight()
Definition: camera.cpp:45
bool close_device()
Definition: camera.cpp:76
int width
Definition: camera.h:19
int height
Definition: camera.h:19
~v4l_capture()
Definition: camera.cpp:15
png_bytep png_bytep png_size_t length
int getWidth()
Definition: camera.cpp:40
png_uint_32 i
png_infop png_uint_32 * width
bool init_mmap()
Definition: camera.cpp:140
#define min(a, b)
int init(size_t _width, size_t _height, unsigned int devId)
Definition: camera.cpp:23
png_infop png_uint_32 png_uint_32 * height
bool write_img(uchar *ret)
Definition: camera.cpp:86
v4l_capture()
Definition: camera.cpp:10
bool open_device()
Definition: camera.cpp:63
int free()
bool init_device()
Definition: camera.cpp:209
std::string dev_name
Definition: camera.h:18
png_size_t start
bool init_all(size_t _width, size_t _height, unsigned int _devId)
Definition: camera.cpp:50
int fd
Definition: camera.h:19
bool stop_capturing()
Definition: camera.cpp:323
cv::Mat frame
Definition: camera.h:17
void uninit_device()
Definition: camera.cpp:288
unsigned int n_buffers
Definition: camera.h:21
bool read_frame(void)
Definition: camera.cpp:117
uchar * capture()
Definition: camera.cpp:33
bool start_capturing()
Definition: camera.cpp:294


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:49