一、buffer出队列应用层代码
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0)
printf("dqbuf fail\n");
fwrite(buffers[buf.index].start, buf.bytesused, 1, file_fd);
二、驱动层调用流程
static long __video_do_ioctl(struct file *file,
unsigned int cmd, void *arg)
{
struct video_device *vfd = video_devdata(file);
const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
void *fh = file->private_data;
struct v4l2_fh *vfh = NULL;
struct v4l2_format f_copy;
int use_fh_prio = 0;
long ret = -EINVAL;
... ...
case VIDIOC_DQBUF:
{
struct v4l2_buffer *p = arg;
if (!ops->vidioc_dqbuf)
break;
//类型判断
ret = check_fmt(ops, p->type);
if (ret)
break;
//调用具体的vidioc_dqbuf
ret = ops->vidioc_dqbuf(file, fh, p);
if (!ret)
dbgbuf(cmd, vfd, p);
break;
}
... ...
}
vidioc_dqbuf
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
{
struct vivi_dev *dev = video_drvdata(file);
return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
}
int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
{
struct vb2_buffer *vb = NULL;
int ret;
if (q->fileio) {
dprintk(1, "dqbuf: file io in progress\n");
return -EBUSY;
}

本文解析了V4L2驱动层的vidioc_dqbuf函数如何从vb2_queue的done_list中获取已填充数据的buffer,并将其信息传递给用户空间。通过实例展示了buffer出队过程,包括内存映射、状态检查和数据填充等关键步骤。

595

被折叠的 条评论
为什么被折叠?



