Linux驱动 2026年8月7日 6 分钟

V4L2子系统8-从零写虚拟摄像头驱动

static struct video_device airspy_template = {
	.name                     = "AirSpy SDR",
	.release                  = video_device_release_empty,
	.fops                     = &airspy_fops,
	.ioctl_ops                = &airspy_ioctl_ops,
};

/* 构造一个vb2_queue */
	/* Init videobuf2 queue structure */
	s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
	s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
	s->vb_queue.drv_priv = s;
	s->vb_queue.buf_struct_size = sizeof(struct airspy_frame_buf);
	s->vb_queue.ops = &airspy_vb2_ops;          // vb2_ops, 硬件相关的操作函数
	s->vb_queue.mem_ops = &vb2_vmalloc_memops;  // vb2_mem_ops, 辅助结构体,用于mem ops(alloc、mmap)
	s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
	ret = vb2_queue_init(&s->vb_queue);
				q->buf_ops = &v4l2_buf_ops;    // vb2_buf_ops, 用于APP和驱动传递参数

// 分配/设置video_device结构体
s->vdev = airspy_template;
s->vdev.queue = &s->vb_queue;    // 指向前面构造的vb2_queue

// 初始化一个v4l2_device结构体(起辅助作用)
/* Register the v4l2_device structure */
s->v4l2_dev.release = airspy_video_release;
ret = v4l2_device_register(&intf->dev, &s->v4l2_dev);

// video_device和4l2_device建立联系
s->vdev.v4l2_dev = &s->v4l2_dev;

// 注册video_device结构体
ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
		__video_register_device
			// 根据次设备号把video_device结构体放入数组
			video_device[vdev->minor] = vdev;
			
			// 注册字符设备驱动程序
			vdev->cdev->ops = &v4l2_fops;
			vdev->cdev->owner = owner;
			ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);

上一篇 V4L2子系统7-videobuff2情景分析

下一篇 V4L2子系统9-UVC摄像头