V4L2(video 4 linux 2) 可以支持多种设备,它可以有以下几种接口: 1. 视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的. 2. 视频输出接口(video output interface):可以驱动计算机的外围视频图像设备--像可以输出电视信号格式的设备. 3. 直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU. 4. 视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号. 5. 收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流.(只写过FM的驱动下面着重讲解这种应用.) V4L2驱动的主要功能是使程序有发现设备的能力和操作设备.它主要是用过一系列的回调函数来实现这些功能.像设置高频头的频率,帧频,视频压缩格式和图像像参数等等(在我写的FM驱动中就主要是设置频率,设置音量等). 一个视频驱动很可能还要有处理PCI总线,或USB总线的部分,通常会有一个内部一I2C接口.然后还有一个V4L2的子系统接口.这个子系统是围绕video_device这个结构体建立的,它代表的是一个V4L2设备.讲解进入这个结构体的一切. V4L2是一个两层的驱动系统.顶层是videodev模块,当videodev初始化时,它注册一个主设备号为81的(参考Documentation/devices.txt)字符设备,同时设置字符设备的功能函数.所有的V4L2驱动都是videodev的client端,videodev通过V4L2驱动调用client驱动.当一个V4L2驱动初始化时,它会注册每一个挂在videodev上的设备,这个设备通过videodev的包含V4L2驱动的结构体(此结构体包含V4L2的驱动方法、一个次设备号,以及其他两个详细信息)来挂在videodev上.V4L2的驱动方式很象通常的linux字符设备驱动,但是又有不同的参数.Videodev扮演这一个环绕在V4L2驱动周围的薄壳的角色,videodev作为一个模块实现,所有的V4L2驱动也是作为模块实现. 当一个驱动初始化时,它列举出所有的在系统中将要挂在它上面的设备.对于每个设备都有一个video_device结构体,并使用video_register_device()注册此设备./* * Newer version of video_device, handled by videod***.c * This version moves redundant code from video device code to * the common handler */ struct video_device{ /* device ops */ const struct v4l2_file_operations *fops; /* sysfs */ struct device dev; /* v4l device */ struct cdev *cdev; /* character device */ /* Set either parent or v4l2_dev if your driver uses v4l2_device */ struct device *parent; /* device parent */ struct v4l2_device *v4l2_dev; /* v4l2_device parent */ /* device info */ char name[32]; int vfl_type; /* ''minor'' is set to -1 if the registration failed */ int minor; u16 num; /* use bitops to set/clear/test flags */ unsigned long flags; /* attribute to differentiate multiple indices on one physical device */ int index; int debug; /* Activates debug level*/ /* Video standard vars */ v4l2_std_id tvnorms; /* Supported tv norms */ v4l2_std_id current_norm; /* Current tvnorm */ /* callbacks */ void (*release)(struct video_device *vdev); /* ioctl callbacks */ const struct v4l2_ioctl_ops *ioctl_ops;}; 以我写的FM为例看三个结构体: static const struct v4l2_ioctl_ops si470x_ioctl_ops = { .vidioc_querycap = si470x_vidioc_querycap, .vidioc_queryctrl = si470x_vidioc_queryctrl, .vidioc_g_ctrl = si470x_vidioc_g_ctrl, .vidioc_s_ctrl = si470x_vidioc_s_ctrl, .vidioc_g_audio = si470x_vidioc_g_audio, .vidioc_g_tuner = si470x_vidioc_g_tuner, .vidioc_s_tuner = si470x_vidioc_s_tuner, .vidioc_g_frequency = si470x_vidioc_g_frequency, .vidioc_s_frequency = si470x_vidioc_s_frequency, .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,}; VFL_TYPE_VTX 代表视传设备. 设备的注销方法为: void video_unregister_device(struct video_device *vfd); 参考:Video for Linux Two Driver Writer''s Guide The Video4Linux2 API: an introduction http://lwn.net/Articles/203924/
|