V4L2全名为Video For Linux 2,它是针对Linux系统的视频设备处理架构。视频设备主要包括输入设备(摄像头)及输出设备(显示设备)。html
1、 Linux的V4L2架构介绍linux
V4L2的初衷是想为linux系统创建统一的视频类设备处理模型,让驱动开发者依靠其驱动模型轻松的完成video设备的驱动,让视频应用程序能够轻松的使用其接口完成应用程序开发。V4L2的总体架构以下图所示:编程
Ø video设备缓存
视频设备按输入输出来看,输入设备常见的就是摄像头了,输出设备常见的就是显示器、电视机。数据结构
Ø video设备接口架构
l 摄像头接口通常有:框架
ITU-R BT601/656:国际电信联盟针对数字电视演播室的视频接口及数据流格式所作的标准,比较老一点的手机摄像头通常都采用这种接口。ide
MIPI CSI:移动行业处理器接口联盟定义的摄像头数字串行接口,是当今主流的手机摄像头接口。函数
USB:USB摄像头通常常见在台式机上,USB协议中有专门针对video设备的接口类(interfaceclass=0x0E)。优化
l 视频显示接口通常有:
HDMI:高清晰度多媒体接口,可同时传输音频及视频信号,普遍用于数字机顶盒、我的电脑、平板电脑、高清数字电视当中。
VGA:它是一种模拟信号视频接口,普遍用于PC电脑与显示器中,几乎全部显卡都支持该接口。数字电路中使用该类接口须要用到数模视频编码器,将视频的数字信号转化为模拟信号进行传输。
TV-out:TV-out只是一个泛指,指电视中常见的视频模拟接口,如AV接口,S端子,YPbPr接口等。同VGA同样,数字电路中使用该类接口须要用到TV视频编码器,将视频的数字信号转化为TV模拟信号进行传输。
Ø video设备接口驱动
该部分须要驱动开发者针对不一样的视频设备接口,完成其接口驱动。
Ø video设备驱动
该部分是驱动开发者在进行视频设备驱动开发时,须要重点实现的对象。驱动开发者须要根据V4L2提供的驱动模型,完成对具体视频设备硬件控制的底层实现。Linux为开发者提供了V4L2驱动开发的示例源码:“/drivers/media/video/vivi.c”。
Ø V4L2核心
该部分是Linux视频设备的架构核心,它对下为驱动开发者提供统一的视频设备驱动开发模型,对上为应用开发者提供操做视频设备的统一接口。其在linux中的核心源码路径为:“/drivers/media/video/v4l2-dev.c”。
Ø V4L2应用接口
应用程序经过V4L2提供read()、write()、ioctl()编程接口,来控制操做视频设备,如:设置图像分辨率、视频数据格式、开始/结束视频捕获等等。
2、 V4L2设备驱动编写
Linux的video设备驱动实现,驱动开发者须要按照V4L2的驱动模型进行设计,该驱动模型主要围绕核心数据结构struct video_device来展开设计,经过该数据结构来完成视频设备的分配、设置、注册等工做。驱动程序须要重点实现两个操做集:v4l2_file_operations和v4l2_ioctl_ops,V4L2架构最终会调用这两个操做集中的函数接口,来完成对视频设备硬件的控制。其实现流程以下图所示:
3、 V4L2_subdev与v4l2_device的出现
V4L2 驱动随着硬件的变化也愈来愈复杂,如今大部分设备里面包含了多个子设备IC,比较常见的子设备如编解码的装置、传感器、摄像头控制器等。一般这些IC经过 i2c 总线链接到主板,这些设备都统称为sub-devices。
在很长的一段时间里 V4L2 被限制只能在 video_device 结构体里面建立,而且用video_buf控制视频缓存,这意味着全部的驱动建立本身的实例都将链接到本身的sub-devices,这些工做一般很复杂并常常引发错误,许多常见的代码由于缺少一个框架而没法重构。所以 V4L2 框架做了相应的优化:它有一个 v4l2_device 结构做为设备实例,一个v4l2_subdev结构做为子设备实例,video_device 结构包含了v4l2_device 节点,每一个视频设备都采用 v4l2_device 结构来表示。为了提供统一的接口给这些子设备,内核将涉及到子设备控制的那部分独立了出来,用 struct v4l2_subdev 来表示以方便用户实现 v4l2 驱动程序。现现在的V4L2设备关系用一个比较粗糙的图来表示他们之间的关系,大体为:
设备实例(v4l2_device)
|______子设备实例(v4l2_subdev)
|______视频设备节点(video_device)
|______文件访问控制(v4l2_fh)
|______视频缓冲的处理(videobuf/videobuf2)