我有一个简单的c ++程序,其中的以下代码在线程中运行,以获取恒定的网络摄像头。第一次,一切正常。但是在关闭应用程序并再次运行之后。 select()函数超时,我从相机无法得到任何图像。尽管LED照应点亮。该摄像头无需重新插入任何其他wecam应用程序即可使用。看来我的代码没有正确重置或关闭?
fd = v4l2_open("/dev/video0", O_RDWR | O_NONBLOCK, 0);
// check if device is ready
v4l2_capability capability{};
ioctl(fd, VIDIOC_QUERYCAP, &capability);
// set Image format
v4l2_format imageFormat;
imageFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
imageFormat.fmt.pix.width = s.width;
imageFormat.fmt.pix.height = s.height;
imageFormat.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
imageFormat.fmt.pix.field = V4L2_FIELD_NONE;
// tell the device you are using this format
ioctl(fd, VIDIOC_S_FMT, &imageFormat);
v4l2_requestbuffers req{};
req.count = buffers.size();
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS, &req);
for (unsigned i = 0; i < req.count; i++) {
// query buffer
v4l2_buffer buf{};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
xioctl(fd, VIDIOC_QUERYBUF, &buf);
// map data to buffer
auto b = v4l2_mmap(nullptr, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
buffers[i].start = reinterpret_cast<uint8_t *>(b);
buffers[i].length = buf.length;
}
for (unsigned i = 0; i < req.count; i++) {
v4l2_buffer buf{};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
xioctl(fd, VIDIOC_QBUF, &buf);
}
auto type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);
while (bKeepRunning) {
fd_set fds;
timeval tv{};
int r;
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 1;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
if (r <= 0) {
continue;
}
v4l2_buffer buf{};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
// retreive buffer
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
continue;
}
int jpegSubsamp, jpegW, jpegH;
auto start = buffers[buf.index].start;
auto data = jpgd::decompress_jpeg_image_from_memory(start, buf.bytesused, &jpegW, &jpegH, &jpegSubsamp, 3);
// release buffer
xioctl(fd, VIDIOC_QBUF, &buf);
}
xioctl(fd, VIDIOC_STREAMOFF, &type);
for (auto &buffer: buffers) {
if (buffer.length == 0) continue;
v4l2_munmap(buffer.start, buffer.length);
}
v4l2_close(fd);