Video for Linux two(Video4Linux2)简称 V4L2,是 V4L 的改进版。V4L2 是 linux操作系统下用于视频和音频数据采集设备的驱动框架,为驱动和应用程序提供了一套统一的接口规范。
在 Linux 下,所有外设都被看成一种特殊的文件,成为“设备文件”,可以象访问普通文件一样对其进行读写。采用 V4L2 驱动的摄像头设备文是/dev/videoX以及一些子设备/dev/v4l-subdevX。V4L2 支持两种方式来采集图像:内存映射方式(mmap)和直接读取方式(read)。应用层通过 open/ioctl/close 等函数来操作V4L2 设备文件的方式控制 camera 设备。
V4L2 支持的设备:
CRM 即 camera request manager,创建了 V4L2 根设备/dev/video0,供所有子设备注册。
每个子设备实现特定功能,如音视频混合,编解码等。对于 camera,有如下子设备:
SENSOR, IFE, ICP, LRME, JPEG, FD, CPAS, CSIPHY, ACTUATOR, CCI, FLASH,EEPROM, OIS 等。
通过设备文件/dev/v4l-subdevX 供应用层(CSL)调用其功能。
几个重要的结构体
Kernel V4l2 的文档:
https://www.kernel.org/doc/html/v4.9/media/kapi/v4l2-core.html
主要的任务就是负责向内核注册字符设备。
此结构体既可以动态分配,也可以嵌入到一个更大的结构体中。
动态分配方法如下:
- struct video_device *vdev = video_device_alloc();
- if (vdev == NULL)
- return -ENOMEM;
- vdev->release = video_device_release;
也可嵌入到一个大结构体中,此时要实现 release()回调:
- struct video_device *vdev = &my_vdev->vdev;
- vdev->release = my_vdev_release;
设置结构体主要域:
注册视频设备:
- err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
- if (err) {
- video_device_release(vdev); /* or kfree(my_vdev); */
- return err;
- }
这个操作会创建一个字符设备
注销设备:
video_unregister_device(vdev);
这个操作将从 sysfs 中移除设备节点(导致 udev 将其从 /dev 中移除)。
struct v4l2_device:一个硬件设备可能包含多个子设备,比如 camera 包含 sensor 设备,actuator 设备,flash 设备等。而 v4l2_device 就是所有这些设备的根节点,负责管理所有的子设备。
简单设备可以仅分配这个结构体,但在大多数情况下,都会将这个结构体嵌入到一个更大的结构体中。
注册这个设备实例:
v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
注销 v4l2_device 使用如下函数:
v4l2_device_unregister(struct v4l2_device *v4l2_dev);
struct v4l2_subdev:子设备,负责实现具体的功能。
子设备驱动可使用如下函数初始化 v4l2_subdev 结构体:
v4l2_subdev_init(sd, &ops);
向 v4l2_device 注册 v4l2_subdev:
int err = v4l2_device_register_subdev(v4l2_dev, sd);
注销子设备则可用如下函数:
v4l2_device_unregister_subdev(sd);
此后,子设备模块就可卸载,且 sd->dev == NULL。
video_device->v4l2_file_operations
实现文件类操作,比如 open,close,read,write,mmap 等。但是 ioctl 是不需要实现的,一般都是用 video_ioctl2 代替。
.unlocked_ioctl = video_ioctl2,
video_device->v4l2_ioctl_ops
V4L2 导出给应用层使用的所有 ioctl。只要实现需要用的,如:
v4l2_subdev->v4l2_subdev_ops 及其子函数:
必须实现的:
v4l2_subdev_core_ops
其它可按需选择,如:
v4l2_subdev_video_ops
V4L2 是一个字符设备,通过设备文件向应用层提供各种功能。应用层可以像操作普通文件一样 open/close V4L2 设备文件,而 V4L2 的大部分功能都是通过设备文件的 ioctl 导出的。
驱动对应用层提供的设备节点,V4L2 相关设备文件:
其中部分子设备类型如下:
//未完待续...