Linux下v4l2框架的摄像头驱动入队出队失败解决方法(camera->dqbuf: dequeue buffer timeoutcamera->eqbuf: Invalid argument)

开门见山:

方法1更改虚拟机USB兼容版本

进入虚拟机设置

由2.0改为3.0

 

方法二更改队列长度

 一般为4到10,自己多试试,找到最稳定那个就行

方法三更改初始化延时

不同摄像头性能不一样,超时检测稍微设长一点也没关系 

方法四换USB端口(玄学)

有些笔记本电脑不同的USB端口性能不一样

方法五更改图片采集格式(玄学)

MJPG和YUYV换一下

方法六重启虚拟机(玄学)

能解决99%的问题但不一定能解决这个问题

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Linux上使用v4l2库读取IMX415摄像头的数据并保存到内存中,你可以按照以下步骤进行: 1. 打开摄像头设备: ```c int fd = open("/dev/video0", O_RDWR); if (fd == -1) { perror("无法打开设备"); return EXIT_FAILURE; } ``` 2. 设置摄像头参数: ```c struct v4l2_format format; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = <设置摄像头图像宽度>; format.fmt.pix.height = <设置摄像头图像高度>; format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; // 根据摄像头支持的格式进行设置 format.fmt.pix.field = V4L2_FIELD_NONE; if (ioctl(fd, VIDIOC_S_FMT, &format) == -1) { perror("无法设置摄像头参数"); close(fd); return EXIT_FAILURE; } ``` 3. 请求帧缓冲: ```c struct v4l2_requestbuffers req; req.count = <设置帧缓冲个数>; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { perror("无法请求帧缓冲"); close(fd); return EXIT_FAILURE; } ``` 4. 映射帧缓冲到用户空间: ```c struct v4l2_buffer buf; for (int i = 0; i < req.count; i++) { buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) { perror("无法查询帧缓冲"); close(fd); return EXIT_FAILURE; } void* addr = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (addr == MAP_FAILED) { perror("无法映射帧缓冲"); close(fd); return EXIT_FAILURE; } } ``` 5. 入队帧缓冲: ```c for (int i = 0; i < req.count; i++) { buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) { perror("无法入队帧缓冲"); close(fd); return EXIT_FAILURE; } } ``` 6. 开始视频流: ```c enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) { perror("无法开始视频流"); close(fd); return EXIT_FAILURE; } ``` 7. 循环读取帧数据并保存到内存: ```c while (<终止条件>) { fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); // 设置超时时间 struct timeval timeout; timeout.tv_sec = <设置超时秒数>; timeout.tv_usec = <设置超时微秒数>; // 等待帧缓冲可用 int ret = select(fd + 1, &fds, NULL, NULL, &timeout); if (ret == -1) { perror("select"); break; } else if (ret == 0) { printf("select timeout\n"); continue; } // 帧缓冲 if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) { perror("无法帧缓冲"); break; } // 处理帧数据 // 将buf.start指向的数据保存到内存中 // 入队帧缓冲 if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) { perror("无法入队帧缓冲"); break; } } ``` 8. 停止视频流和清理资源: ```c enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) { perror("无法停止视频流"); } for (int i = 0; i < req.count; i++) { munmap(addr[i], buf.length); } close(fd); ``` 请注意,上述代码仅为简单示例,实际使用时可能需要根据自己的需求进行适当的修改和完善。同时,还需了解更多关于v4l2库的使用和摄像头设备的特定参数设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值