APP下载

V4L2在TMS320DM8168高清视频监控系统中的实现

2014-09-18杨振永王延杰王明佳韩秋蕾陈怀章

电视技术 2014年13期
关键词:缓冲区高清总线

杨振永,王延杰,王明佳,韩秋蕾,陈怀章

(1.中国科学院 长春光学精密机械与物理研究所,吉林 长春 130033;2.中国科学院大学,北京 100049)

近年来,随着数字多媒体技术的飞速发展,安防监控领域对视频质量有了越来越高的要求,特别是由于犯罪分子作案手段越来越难以发觉捕捉,标清视频很难发现其中的细节[1]。因此,视频设备的高清化成为了安防监控领域发展的必然趋势,而基于高清设备的软件开发也成为了必须要解决的问题。

V4L2(Video for Linux 2)是嵌入式Linux操作系统为音视频采集和显示而提供的驱动框架,在Linux 2.5.46版本以后正式成为Linux内核的一部分,它为音视频采集和显示应用提供了API接口[2]。目前V4L2已支持多种视频设备的采集和显示,同时驱动本身经过不断的完善,也可以提供越来越多的图像预处理功能。基于V4L2的应用开发已经十分成熟,但是新的设备必然带来新的问题,V4L2在高清视频采集中也会受到资源不足等问题的困扰。

本文针对TMS320DM8168高清视频监控系统,首先介绍了V4L2采集的译码芯片TVP7002及其与DM8168的接口连接,之后介绍了V4L2视频设备的驱动设计和应用程序开发,并对其中出现的问题进行了分析解决,最后给出了视频监控系统的效果。结果表明,V4L2在DM8168高清视频监控系统中具有良好的可靠性和稳定性,可以为系统提供稳健的高清视频流。

1 系统总体结构

以TMS320DM8168为核心的高清视频监控系统,主要由高清视频的采集和显示模块、视频处理模块、SATA存储模块和网络传输模块4部分组成,总体结构如图1所示。

由图中可以看出,TMS320DM8168内部集成的Cortex-A8 ARM处理器是系统的主处理器,控制着整个系统的运行,单片系统内部集成的C674x DSP处理器主要完成视频算法的处理,Cortex-M3 ARM处理器是系统多媒体控制器,控制了视频的高清视频处理子系统HDVPSS和加速视频压缩解压缩的硬件加速器HDVICP2,HDVPSS控制着视频采集与显示模块,SATA控制器控制着视频数据的SATA存储,网络控制器控制着网络传输部分,支持10/100/1 000 Mbit/s的网络传输[3]。

图1 系统总体框图

2 视频接口设计

系统使用TVP7002作为视频译码芯片,与DM8168对应的视频采集接口连接。DM8168单片系统中视频采集和显示部分以高清视频处理子系统HDVPSS为基础,HDVPSS支持两个独立的视频采集端口VIN[0]和VIN[1],能够支持两路并行的高达165 MHz的视频采集,其中VIN[0]可采集单通道16/24 bit(YCbCr/RGB)视频或者双通道 8 bit(YCbCr)视频,VIN[1]可配置为单通道 16 bit(YCbCr)视频或者双通道8 bit(YCbCr)视频,当采集高清视频时,视频需要符合BT.1120协议,当采集标清视频时,符合BT.656协议;HDVPSS还有3个独立的视频输出端口VOUT[0]、VOUT[1]和HDMI输出端口,其中VOUT[0]最高可显示30 bit视频,它支持RGB、YUV444、Y/C和BT.656等多种格式;VOUT[1]可显示16 bit视频,它支持Y/C和BT.656格式;HDMI输出接口,支持HDMI 1.3a协议,最高频率达到162 MHz。此外,VIN[]和VOUT[]都支持内嵌同步信息和独立同步信息两种同步方式。

TVP7002支持3个独立的数字通道,支持480i、576i、480p、576p、720p、1 080i和1 080p格式的视频译码,输出时钟从12 MHz到165 MHz不等,输出可为30 bit RGB/YCbCr 4∶4∶4或20 bit 4∶2∶2视频,同步信息可以内嵌到视频数据中或者独立于视频数据之外,芯片可以通过I2C总线配置。系统的视频接口关键连接如图2所示。

由图中可以看出,视频采集选用了VIN[0]通道采集16 bit YCbCr 4∶2∶2高清视频,其中VIN[0]_D[15:8]传输亮度分量Y,VIN[0]_D[7:0]传输色度分量Cb/Cr,视频同步信息嵌入到有效数据之中。DM8168通过I2C总线配置TVP7002芯片,芯片I2C地址选择引脚接高电平,其I2C地址为7 bit 1011101。

图2 视频采集接口

视频显示接口使用HDMI输出通道,HDMI通道最高输出频率达到162 MHz,每对差分线速度达到3.4 Gbit/s,因此,为了确保良好的信号完整性,增加了TPD12S521静电释放ESD保护芯片。

3 V4L2驱动程序开发

DM8168中HDVPSS系统管理着视频的采集和显示,V4L2驱动作为HDVPSS的一部分,为视频采集程序提供了API接口函数。HDVPSS的软件结构如图3所示。

图3 VPSS软件结构图

由图中可以看出,VPSS硬件可以分为2个部分:Cortex-M3和Cortex-A8,其中Cortex-M3管理VPSS的视频、图像的采集和显示管道,Cortex-A8为驱动提供了硬件抽象层FVID2,为驱动程序提供了底层支持;Cortex-M3和Cortex-A8之间的通信通过SysLink管理。Cortex-A8上运行Linux操作系统,它分为内核空间和用户空间,驱动程序V4L2和FBDEV以及文件系统管理接口SYSFS都在内核空间,它们为用户空间的应用程序提供API接口函数。FBDEV是帧缓冲设备,主要用于LCD显示,它将内存中的图像数据与LCD的像素位置一一对应,具有操作简单、灵活多变的特点,本系统HDMI输出接口采用的就是帧缓冲驱动,这里不再详细介绍。SYSFS接口为应用程序控制驱动提供了接口,可以配置视频显示驱动,改变显示通道[4]。

V4L2驱动是Linux中标准的视频采集和显示驱动,是Linux内核中关于视频设备的中间驱动层。它在Linux内核中注册为字符设备,其主设备号为81[5],从设备号为0~255,其中0~63用于视频设备,64~127用于音频设备,192~223用于Teletext设备,224~255用于VBI设备。理解V4L2驱动前需要先了解platform driver平台驱动的概念。platform与I2C、PCI等总线类似,都是为了便于管理系统的外设资源,将设备和驱动连接在一起,但是platform是一种虚拟总线,并没有严格的总线协议,只是为了将外设挂载在一种总线上,便于统一管理,在SOC单片系统中,platform driver平台驱动很常见,它有独立的注册函数和注销函数,即platform_driver_register()和platform_driver_unregister()。

V4L2视频采集驱动有两种实现方法:将采集设备作为普通V4L2设备,直接控制TVP7002译码芯片实现视频数据的采集,或者利用内核中实现好的V4L2驱动框架,将译码芯片挂载为V4L2的子设备,通过实现V4L2驱动的接口函数,完成视频的采集[6]。第1种方法代码量大,难度也大,第2种方法工作量较小,可移植性强,因此,选择了第2种方法实现V4L2采集驱动。

V4L2采集驱动从注册平台驱动开始,将采集驱动注册到platform总线上。在driver的probe()探测函数里完成资源分配以及V4L2设备的注册。在probe()函数中video_device结构体与视频采集设备是一一对应的,每个video_device都有自己的采集设备。本系统的采集驱动支持4路视频通道,在调用video_register_device()函数后,将在/dev目录上生成video0、video4、video5和video6这4个设备节点,每个视频通道都有各自的操作函数集 v4l2_file_operations和控制函数集v4l2_ioctl_ops。除了以上内容,probe()函数还要将V4L2子设备与V4L2设备绑定在一起。由于TVP7002使用I2C总线配置,因此,最初TVP7002是注册为I2C子设备的,此时需要使用函数v4l2_i2c_new_subdev_board()将I2C子设备添加为一个V4L2子设备。该函数主要完成2个工作:根据函数传递的I2C设备相关信息向I2C总线添加(或探测)一个I2C设备,然后向V4L2驱动注册V4L2子设备。DM8168有2个通用的I2C控制器,TVP7002使用第2个,因此,调用v4l2_i2c_new_subdev_board()函数前需要使用i2c_get_adapter()函数获取对应的I2C适配器。

TVP7002作为V4L2的子设备v4l2_subdev,首先会注册为I2C子设备i2c_client,为了将两者关联起来,在TVP7002驱动的probe函数中调用了v4l2_i2c_subdev_init()函数,在该函数中两者将彼此的*private指针指向对方。v4l2_i2c_subdev_init()函数还调用了v4l2_subdev_init()函数将TVP7002的操作函数集赋给对应V4L2子设备的操作函数。TVP7002作为v4l2_subdev,对应/dev/video0设备节点,主要实现了core函数集和video函数集两类,其中core函数集中定义了对TVP7002芯片的寄存器配置函数,如获得芯片id函数g_chip_ident、寄存器值获取函数g_register、寄存器值设置函数s_register等,video函数集为V4L2的部分操作函数提供了底层实现。此外,TVP7002的probe()函数中还设置了芯片的初始化状态。

V4L2设置完视频采集参数后,需要为将要采集到的视频分配缓存,对视频缓冲帧的管理是V4L2非常重要的一部分,它关系到视频能否正确地传递给应用层,一般V4L2驱动会使用Linux提供的videobuf_queue结构管理视频的缓冲帧,它为驱动提供了统一的V4L2用户空间接口,增加了可移植性。Videobuf层位于V4L2驱动层和应用层之间,包含一系列的函数,可实现标准POSIX I/O系统调用以和V4L2的ioctl()函数调用,它们可用于管理帧视频的缓冲区分配、FIFO队列出入和流控制等。

Videobuf支持3种类型的缓冲区,第1种是在物理和虚拟地址上都不连续的缓冲区,这种缓冲区在Linux中非常常见,几乎所有的用户空间缓冲区都是这种类型,但是这种分配方式需要硬件支持分散/聚集DMA操作;第2种是在物理上连续,在虚拟地址上不连续的缓冲区,这种缓冲区使用vmalloc()函数分配,很难用于DMA操作;第3种是在物理和虚拟地址上都连续的缓冲区,这种缓冲区可以很方便地使用DMA操作,但是容易造成内存空间的溢出[7]。

为了方便管理缓冲区,videobuf提供了4个接口函数buf_setup()、buf_prepare()、buf_queue()和 buf_release()。与之对应,在v4l2_ioctl_ops函数组中提供了vidioc_reqbufs()、vidioc_qbuf()、vidioc_streamon()和 vidioc_streamof()这4个函数。int(*buf_setup)(struct videobuf_queue*q,unsigned int*count,unsigned int*size)用于通知videobuf申请的I/O缓冲帧的信息,包括缓冲区的数量(在2~32之间)、缓冲区类型和大小等;int(*buf_prepare)(structvideobuf_queue*q,structvideobuf_buffer*vb,enum v4l2_field field)用于设置缓冲帧的宽、高等信息;buf_queue()和buf_release()用于实现缓冲帧数据流的启停。

4 视频采集应用程序开发

V4L2驱动提供了符合POSIX I/O标准的系统调用函数open()、read()以及控制函数ioctl()。通过这些函数可以方便地完成视频的采集工作。采集程序流程图如图4所示。

图4 视频采集流程图

这里以采集720p 60 YCbCr 4∶2∶2高清视频为例介绍视频采集的流程:

1)打开视频设备:本驱动设备节点为/dev/video0,可以使用cap_fd=open(“/dev/video0”,O_RDWR)打开视频设备。

2)设置视频格式:在申请缓冲区前,需要判断视频的格式,首先查询设备处理能力VIDIOC_QUERYCAP[8],若设备支持视频采集,则查询采集的视频格式VIDIOC_QUERY_DV_PRESET,本例中得到的是V4L2_DV_720P60,之后根据得到的视频格式,设置参数VIDIOC_S_DV_PRESET,以上操作均是使用V4L2的ioctl()函数完成的。

3)申请帧缓冲区:V4L2支持两种不同的帧缓冲区操作:映射内存mmap和用户指针类型内存userptr。本系统采集的都是高清视频,一帧720p图像将近1.76 Mbyte,而由于硬件限制,DM8168采集和显示的帧缓冲区都不能低于4个,DM8168很难留出这么大的空间用于内存映射,因此,这里使用用户指针类型的内存。具体的操作步骤是:使用VIDIOC_G_FMT获得当前视频宽、高等信息、使用VIDIOC_S_FMT设置视频信息、使用VIDIOC_REQBUFS申请4个用户指针类型的帧缓冲区,内存分配使用LCD设备缓冲区,这样可以直接显示。

4)缓冲帧入列:videobuf通过将缓冲帧送入FIFO队列来保证视频流的顺序,这里使用VIDIOC_QBUF将申请到的每个帧缓冲区依次送入FIFO队列中。

5)采集过程:视频的采集过程实际是FIFO队列的入队出队过程,该过程使用VIDIOC_STREAMON启动,使用VIDIOC_STREAMOFF终止,其中VIDIOC_DQBUF使视频帧出队列,VIDIOC_QBUF使视频帧入队列,取出的视频帧可以做相应的处理。

6)关闭视频设备:采集结束后需要释放缓冲区,并且关闭设备节点close(cap_fd)。

5 采集结果测试

这里以采集720p 60高清视频为例,测试V4L2驱动及应用程序的可靠性。

将V4L2视频采集驱动编译为独立的内核模块,加载该模块,编译并运行采集应用程序,显示得到的视频如图5所示。

图5 视频采集的图像

采集到的高清视频流畅,没有出现丢帧的情况,由图中可以看到采集到的画面质量很好,证明了V4L2驱动和应用程序的可靠性。

6 结束语

本文主要介绍了V4L2在DM8168高清视频监控系统中的驱动和应用实现。文中首先介绍了V4L2高清视频的结构基础DM8168高清视频监控系统,特别是视频的输入输出接口,之后V4L2的软件基础HDVPSS以及视频采集驱动在HDVPSS中的位置特点,最后详细介绍了V4L2驱动程序的设计实现以及采集应用程序的流程步骤。通过采集720p 60高清视频,表明本系统设计实现的V4L2驱动程序以及应用程序可以稳定可靠地采集高清视频,为高清视频监控系统提供优质的高清视频数据。

[1]苏财贵,叶宇煌,苏凯雄.HDMI接口在H.264高清视频编解码系统中的应用[J].电视技术,2012,36(21):67-70.

[2]黄俊伟,巴义.基于V4L2移动视频监控系统的研究与设计[J].电视技术,2012,36(17):159-162.

[3]Texas Instruments Incorporated.TMS320DM816x DaVinci video processors[EB/OL].[2013-07-11].http://www.ti.com/lit/ds/symlink/tms320dm8168.pdf.

[4]Texas Instruments Incorporated.DM816X AM389X VPSS video driver user guide PSP 04.00.00.12[EB/OL].[2013-07-24].http://processors.wiki.ti.com/index.php?oldid=79736.

[5]LIU Y,YU H,ZHANG P.The implementation of embedded image acquisition based on V4L2[C]//Proc.2011 International Conference on Electronics,Communications and Control.[S.l.]:IEEE Press,2011:549-552.

[6]徐家,陈奇.基于V4L2的视频设备驱动开发[J].计算机工程与设计,2010,31(16):3569-3572.

[7]CORBET J.Videobuf:buffer management for V4L2 drivers[EB/OL].[2013-07-23].http://lwn.net/Articles/363349.

[8]赵玉峰.基于嵌入式Linux的实时视频通信的实现[J].电视技术,2012,36(19):189-192.

猜你喜欢

缓冲区高清总线
高清大脑皮层发育新图谱绘成
教你玩转AV设备(一):4K高清播放机使用指南
基于PCI Express总线的xHC与FPGA的直接通信
机载飞控1553B总线转以太网总线设计
一种基于CAN总线的误码测试方法
基于网络聚类与自适应概率的数据库缓冲区替换*
一类装配支线缓冲区配置的两阶段求解方法研究
数码单反拍摄高清视频时同期声的收录探索
CAN总线并发通信时下位机应用软件设计
关键链技术缓冲区的确定方法研究