我是在嵌入式设备上使用V4L2的新手,我有两个与V4L2库使用相关的问题:
首先是v4l2_requestbuffers的缓冲区分配:
struct v4l2_requestbuffers req;
CLEAR(req);
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
以后它用于:
if (req.count < 2) {
fprintf(stderr, "Insufficient buffer memory on %s\n",
dev_name);
exit(EXIT_FAILURE);
}
buffers = calloc(req.count, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
errno_exit("VIDIOC_QUERYBUF");
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap(NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
errno_exit("mmap");
}
为了捕获静止图像,req.count为1.为了捕获视频,我们是否需要将req.count数字调整为我们获得良好fps的数字? 这意味着我们必须将req.count从2(在此示例中)更改为合适的数字以获得可接受的fps?
第二个问题是在主循环中使用的超时设置:
static void mainloop(void)
{
unsigned int count;
count = frame_count;
while (count-- > 0) {
for (;;) {
fd_set fds;
struct timeval tv;
int r;
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) {
if (EINTR == errno)
continue;
errno_exit("select");
}
if (0 == r) {
fprintf(stderr, "select timeout\n");
exit(EXIT_FAILURE);
}
if (read_frame())
break;
/* EAGAIN - continue select loop. */
}
}
}
如果我设置
/* Timeout. */
tv.tv_sec = 0;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
我的CPU负载是100%,我必须把它设置为1或2以减少CPU负载。如果我删除超时select()函数,我的CPU负载再次为100%。
从我的阅读中,select()
操作花费了更多的CPU周期,但是我们如何在mainloop()中删除select()和timeout设置?因为当我查看来自高级软件工程师的其他V4L2捕获代码时,我没有看到他们使用超时功能,如上例所示。
所以我的第二个问题是如何避免使用超时select()但仍然保持低CPU负载。