• 110
智能相机的视频帧队列管理程序
设计与实现
南京邮电大学电子与光学工程学院  张仰月
【摘要】智能相机是一种微小型机器视觉系统,可满足多种机器视觉解决方案。选用内部集成了ARM+FPGA 体系结构的Xilinx Zynq-7000芯片,在原有Xilinx UG925参考设计只有硬件或软件处理基础上,基于软硬件协同设计思想进一步优化了智能相机系统框架。深入分析了Linux 系统下的V4L2框架,在充分利用其特性的基础上,设计并实现了智能相机的循环双向链式视频帧队列管理程序。在该视频帧
队列管理和IO 复用的配合下,使用poll 函数监测图像采集、HLS 硬件算法处理、软件算法处理、显示等事件,使软件和硬件图像处理算法得以协同工作。实验结果表明,视频帧管理程序提高了系统吞吐量和可扩展性、降低了系统耦合性、便于添加其他应用,具有一定工程应用参考价值。
【关键词】Zynq-7000;视频帧队列;V4L2框架;智能相机
0  引言
智能相机是一种高度集成化的微小型机器视觉系统,它将智能视觉技术与嵌入式处理硬件平台相结合,提供了具有多功能、模块化、高可靠性的机器视觉解决方案[1]。智能相机处理过程可以划分为三个阶段,分别为图像采集、处理和传输[2]。智能相机选用Xilinx 公司推出的Zynq-7000系列全可编程片上系统,该系列芯片既可以利用FPGA 强大的并行计算能力和复杂的逻辑接口设计,又可以利用ARM 搭建支持的操作系统实现复杂的逻辑控制和算法处理,这样可以较好地支持智能相机系统设计[3]。
队列管理常见于缓解网络拥塞,路由器采用了先来先服务(First In First Serve)的调度算法和尾部丢弃(drop-tail)策略处理网络拥塞,即当队列满时被迫丢包的被动式队列管理[4]。为了提高网络可靠性,人们提出了基于FIFO(First In and First Out)调度策略的主动队列管理机制,即发现拥塞逼近主动降低发送速率管理队列长度[5]。可见在高速传输数据情况下,需要采用队列管理来提高吞吐量和响应速率,高速采集和处理视频帧同样属于这种情况。因此需要一种队列管理策略来提高智能相机的吞吐量和处
理速度。
论文设计了智能相机视频帧队列管理程序,利用此管理程序使得智能相机的三个处理阶段可以有条不紊进行。由于图像处理阶段是基于软硬件协同的方式进行设计,在FPGA 中进行并行算法的硬件加速,在ARM 中搭建linux 操作系统进行应用层软件图像处理算法。视频帧队列管理程序为这种异构多处理体系结构的软硬件协同设计提供了很好支持,并且提高了智能相机软件架构的灵活性和可
扩展性,降低了系统耦合性,方便以后添加其他硬件加速IP 核和软件处理算法,丰富智能相机功能。
1  系统软件架构介绍
智能相机一般要求具备采集图像、图像处理和图像传输等功能。为充分利用Zynq 异构多核资源,智能相机应用层程序设计为多线程程序。包含三个线程:
(a )主线程,基于命令行输入程序和解析XML 配置程序,获得参数初始化视频源(摄像头Vita2000)、硬件加速IP 核(设置分辨率)和DRM 显示管理等,同时生成下面两个线程。
(b )socket 通信线程,基于TCP 和UDP 协议与上位机进行通信,主要用于获取上位机XML 配置文件和传输图像处理结果。
(c )图像处理流水线线程,流水线过程包括从视频源获取视频帧,将此视频帧通过VDMA 通道存入DDR 内存中。然后从DDR
中提取视频帧通过VDMA 通道1放入HLS 硬件加速IP 核中,接着将经过处理的视频帧通过VDMA 通道2存入DDR 中。最后可将此视频帧通过Xylon CVC 传递给ADV7511接口驱动显示器显示或者将此视频帧映射至用户空间进行软件算法处理后通过Socket 传输图像处理结果。这些采集、处理和显示等过程的调用执行主要是基于V4L2框架用poll 函数监测各个子设备状态变化进行驱动。
通过上述三个线程同步完成各自任务组成完整的智能相机采集、处理和传输过程,进而组成完整的智能相机软件架构。其如图1
所示。图1 智能相机系统软件框图
• 111
2  智能相机视频帧队列管理程序设计与实现
2.1  智能相机数据流向设计
视频设备视频流中内存管理是一个复杂过程,包括内存分配、各种状态和流向管理和映射处理等问题,还有视频设备数据格式的复杂多样,有的需要地址不连续内存,有的需要地址连续内存,这也加剧了相应管理的复杂性,由于需要通过VDMA 处理,采用物理地址连续内存。
智能相机数据流是视频设备操作的核心,根据数据流向和子设备在应用层设计3个video_device 管理实体,分别对应Video_In 、Video_Process_In 和Video_Process_Out 。智能相机数据流向图如图2所示。Video_In 的设备索引号为video6,管理从CMOS (Vita2000摄像头)通过VDMA0通道采集视频帧至DDR 内存A 的数据流1。Video_Process_In 的设备索引号为video5,管理从DDR 内存A 中通过VDMA1通道获取视频帧至HLS 硬件算法处理IP 核的数据流2。Video_Process_Out 的设备索引号为video4,管理从HLS 硬件算法处理IP 核获取处理结果通过VDMA1通道存入DDR 内存B 的数据流3。DDR 内存C 为DRM 申请的内存,用于缓存要显示的视频帧。linux 系统中把地址空间分为内核地址空间和用户地址空间,内核空间与用户空间交换数据可以直接read 或write ,这种方式属于帧IO 访问方式,每一帧都要通过IO 操作,需要用户和内核之间进行数据拷贝,速度很慢。也可以通过内存映射方式进行内核与用户空间交换数据,这种方式属于流IO 访问方式,不需要数据拷贝,访问速度比较快,所以选择这种映射方式。其中D 和E 分别就是内核空间内存块B 和C
映射至用户空间的内存块。
图2 智能相机数据流向图
数据流1和数据流3的buffer 类型选择为V4L2_BUF_TYPE_VIDEO_CAPTURE ,两者都是从外部设备捕获视频帧至DDR 内存中。数据流2的buffer 类型选择为V4L2_BUF_TYPE_VIDEO_OUT-PUT ,表
示从DDR 内存中输出视频帧。在linux 中内存分配方式不同,其IO 方式也不同,在V4L2框架中提供多种内存分配方式。V4L2_MEMORY_DMABUF 是在内核空间开辟缓冲区,其缓冲区为物理内存上连续DMA 缓冲区,可以通过VDMA 通道直接在两个设备之间执行DMA 操作,显然内存A 选择此种内存分配方式。V4L2_MEMORY_MMAP 是在内核空间开辟缓冲区,应用通过mmap()系统调用映射到用户空间。这些缓冲区可以DMA 缓冲区、通过vmal-loc()创建的虚拟缓冲区,或者直接在设备的IO 内存中开辟的缓冲区(如果硬件支持),内存B 既需要进行VDMA 操作又需要映射到用户空间,显然内存B 选此种内存分配方式。
linux 提供mmap 系统调用实现设备或文件映射到用户进程的虚拟地址空间,使得用户进程对设备文件的直接读写。mmap 函数原
型为void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset),start 为欲映射区开始地址,设为NULL ,代表让系统自动选定地址,映射成功后返回该地址,在用户空间访问此源地址得到源
视频帧进行软件算法处理。视频帧处理结果放入内存C 映射到用户空间目的地址,即可进行显示。2.2  智能相机视频帧队列管理实现
对于异构多核体系结构,为了充分发挥其丰富资源,使智能相机性能和处理速度提升,必然不能每次
只处理一帧图片,这样就会出现FPGA 在进行硬件加速时,而ARM 在等待FPGA 处理结果,造成大量资源浪费。对于内存A 和B ,涉及到3次缓冲即需要3个缓冲队列,分别要缓冲采集图片、缓冲入HLS 硬件加速、缓冲出HLS 硬件加速,所以每个队列需要4个缓冲区才能够缓存视频帧,合理管理这4个缓冲区至关重要。
通过poll 系统调用函数分别监测Video_In 、Video_Process_In 和Vid-eo_Process_Out 设备文件描述符状态变化,poll 函数原型为int poll(struct pollfd *fds,nfds_t nfds,int timeout),其中pollfd 为一个结构体包含被监视的文件描述符、指定监测文件描述符事件和文件描述符的操作结果事件。被监视的文件描述符可以传递多个结构体,指示poll 可以监视多个文件描述符。监测文件描述符事件有读事件(POLLIN)、写事件(POLLOUT)和错误事件(POLLERR),其中Video_In 和Video_Process_Out 为可读事件,Video_Process_In 为可写事件。结合V4L2采集图片和处理队列命令,具体的程序流程图如图3
所示。
图3 智能相机视频帧队列管理流程图
将内存A 和B (见图2)申请的4个buffer 分别为a1,a2,a3,a4和b1,b2,b3,b4管理成队列,V4L2提供ioctl 命令VIDIOC_QBUF 入缓冲队列和VIDIOC_DQBUF 出缓冲队列。具体视频帧管理如图4所示。当监测到第一帧图片b1存入队列1时,先将其出队列暂时不做任何处理。当监测到第二帧图片b2存入队列1时,将b2出队列,再将b1存入队列2,VDMA 读出b1数据,最后将b1出队列。当监测到第三帧图片b3存入队列,先将其出队列,再将b2存入队列2,VDMA 读出b2数据,最后将b2出队列并
将b1归还给队列重新入队列。当监测到第四帧图片,依然是将队列1前一帧图片入队列2,然后归还队列2前一帧图片给队列1,此时,HLS 处理已完成从队列2中读入的图片了,将其结果入队列3。这样,队列1和队列2构成互为循环,队列3构成循环,充分发挥异构多核丰富资源,FPGA 硬件加速和ARM 软件处理同时进行,完美契合软硬协同处理,提高智能相机系统吞吐量和处理速度。
• 112
图4 智能相机视频帧队列管理
2.3 Linux内核中V4L2队列管理机制分析
在Linux 内核中对于队列管理及buffer 操作标准化,在应用层到驱动层之间建立一层完整、健壮的数据管理层,从而简化驱动开发和避免错误。相应的在接口设计上,通过对buffer 不同状态细化驱动操作,从而提高框架使用范围,提升系统可移植性和稳定性。
在videodev2.h 中定义了v4l2_buffer 结构体,用于用户应用程序与驱动交互。在videobuf2-core.h 中vb2_buffer 结构体中包含v4l2_buffer ,驱动可以对vb2_buffer 的v4l2_buffer 进行操控。在把申请的buffer 入队列时,会将每一个缓存区状态设置为VB2_BUF_STATE_PREPARED 。随后执行list_add_tail(&buf->stream,&q->stream)完成将缓存区buf 的stream 链表数据添加到整个缓存区队列q 的stream 中。缓冲区队列数据结构为一个双向链式循环队列,此结构可高效查询与插入删除操作,便于队列管理。其队列结构图如图5
所示。
图5 linux内核队列结构
队列初始化完成,打开数据流启动摄像头,并将队列q 的streaming 状态置为1。接着应用层poll 函数会调用底层vb2_poll 函数监测队列q 的done_list 中是否有数据,在等待一个buffer 调用时,会释放队列的锁。当监测到有数据写入buffer ,将此buffer 加入done_list 中,设置buffer 状态为VB2_BUF_STATE_DONE 。最后poll 函数监测到buffer ,将此buffer 从done_list 队列里取出,为了保证队列的操作一致性,取队列时会重新获得相关锁。
3  系统调试与结果分析
应用层程序通过XilinxSDK 开发工具调用arm-xilinx-linux-gnue-abi-gcc 和arm-xilinx-linux-g++编译链分别编译.c 和.cpp 文件为目标.o 文件,并调用链接器链接目标文件、系统库文件和opencv 动态链接库生成可执行文件。
修改Linux 内核源代码,打开V4L2内核DEBUG 开关,基于Pet-aLinux 重新编译内核得到UImage 。采用Xilinx 官方ZYNQ 开发板运行可执行文件,从图6Debug 打印信息,可以看出采集前四帧图片时出入队列顺序与分析(分析见3.2节)相同。具体分析当采集第三帧图片时,poll 监测到设备video6和video5有状态变化,video6先将
序号index 为2、模式为vid-cap 、内存类型为dmabuf 、偏移为0x14的buffer 入队列。video5将序号index 为1、模式为vid_out 、内存类型为mmap 、偏移为0x438000的buffer (即第二帧图片所用)先入队列待硬件算法IP 核取走后再将其出队列。最后video6将序号index 为0、模式为vid_cap 、内存类型为dmabuf 、偏移为0x12的buffer (即第一帧图片已用完)入队列。实验结果显示,此视频帧缓冲队列管理程序实现了监测事件、缓冲buffer 、驱动事件的功能,使软件和硬件
处理部分响应速度变快,完美契合软硬协同处理。
图6 Debug打印信息
4  结束语
运行和测试结果表明,在Zynq-7000平台上,基于软硬件协同思想实现了适用于智能相机系统的视频帧队列管理程序。基于此视频帧管理队列,不但完美契合软硬协同处理,提高性能,而且降低了FPGA 硬件加速算法和ARM 软件算法的耦合性,提高了系统的可
扩展性和灵活性,为以后添加其他复杂算法提供了基础,有益于系统的后期开发和维护。参考文献
[1]李佩斌,黄莹,赵誉婷.基于DSP+FPGA 的嵌入式图像处理系统设计[J].现代电子技术,2014,37(20):95-98.
[2]李朗,张索非,杨浩.基于Zynq-7000的视频处理系统框架设计[J].计算机技术与发展,2017(05):192-195.
[3]陆佳华,潘祖龙,彭竞宇.嵌入式系统软硬件协同设计实战指南[M].机械工业出版社,2014.
[4]刘伟彦,孙雁飞,张顺颐,刘斌.一种参数自适应的主动队列管理算法——自适应BLUE[J].电子与信息学报,2009,31(02):462-466.[5]吴春明,姜明,朱淼良.几种主动式队列管理算法的比较研究[J].电子学报,2004(03):429-434.
[6]胡健.基于Zynq 的智能相机图像处理流水线程序优化与实现[J].通讯世界,2017(19):3-4.
[7]鲁永恒.智能相机的异构软件框架设计与实现[D].西安电子科技大学,2014.
[8]Xilinx Corporation.PetaLinux tools documentation:reference guide[EB/OL].[2016-06-01].china.xilinx/.嵌入式多线程编程

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。