0 引言
随着多媒体技术及宽带网络传输技术的发展,视频采集及传输系统作为远程视频监控、可视电话会议和工业自动控制领域的一项关键技术,近年来也得到了飞速的发展。本文所提出的系统是在新一代基于ARM926EJ-S微处理核的嵌入式开发平台上进行的,并将国际上流行的MPEG-4压缩编解码技术和流媒体传输技术相结合。该系统具有较强的实时性、可交互性及便携性。
1 系统开发硬件平台
本设计采用的开发平台是Freescale i.MX家族的MC9328MX21,作为整个系统的微处理器,其ARM926EJ-S核提供了加速的Java支持和高度整合的系统功能模块,如片上模块包括图像加速模块、LCD控制器、USB控制模块、CMOS传感器接口及同步串口等,为开发者进行多媒体应用开发提供了丰富的外围接口。板上集成了64MB SDRAM以及16MBFlash存储器,底板资源包括4个四线RS-232串口、1个10 Mbit·s-1/100 Mbit·s-1自适应以太网接口及音视频采集设备,为系统设计时的交叉编译及多媒体数据的处理提供了方便。
系统的关键外围设备、视频数据的采集所使用的CMOS图像传感器OV9640,与传统的CCD图像传感器相比,具有功耗低、体积小、集成度高等优点,并且OV9640支持VGA、QVGA、CIF等多种解析度,支持的数据格式包括YCrCb 4:2:2、GRB 4:2:2和RGB:RawData这3种,图像帧传输速率达30帧/s。传感器通过CSI模块进行图像数据的采集,然后通过专用总线传输至PRP(eMMA Pre-processor),在PRP中调整图像大小并转换成合适的颜色空间。PRP的输出分成2个通道,通道1输出RGB565格式数据作为LCD的显示,通道2输出YUV420格式数据进行MPEG或者JPEG编码。
|
MC9328MX21的CSI模块有一个8位输入端口,如果传感器的传输超过8位数据,图像传感器通常作为从设备通过I2C端口控制。底层的协议是I2C,高层的协议则由传感器确定。在这里,图像传感器的主时钟由MC9328MX21提供。
2 系统的软件系统设计
2.1 搭建交叉编译环境
由于嵌入式系统选用的是开源的基于ARM微处理器的系统内核ARM-Linux,而在开发板上没有足够的资源运行开发调试工具,所以必须首先搭建好交叉编译调试环境。首先,需要通过在编译时指定target=arm-linux生成适合ARM平台的binutils,它包括了ld、ar和as等一些生成和处理二进制文件的工具。然后,编译生成GCC(GNU Compiler Collection),它能够支持多种语言,如C,C++等,需要注意的是,在编译GCC时需要ARM-linux内核头文件的支持,所以首先需要配置内核#make menuconfig ARCH=ARM来生成对应ARM内核的头文件,这样就可以在配置编译GCC时通过with-headers选项指定编译所需头文件。,还需要编译生成许多用户层应用都要用到的函数库glibc,所有动态链接的程序都要用到它,在编译时需要注意的是打开--enable-add-ons选项,这个开关将打开glibc的附加包,因为我们需要用到linu-xthreads。这样,一个嵌入式ARM-linux下的交叉编译环境就已搭建成功。
2.2 编译制作内核及文件系统
通过make menuconfig配置内核选项,其中的一些关键设置包括指定System Type时打开ARM926T CPUidle、I-Cache 0n和D-Cache,并且由于在进行应用软件开发时需要ARM-linux内核支持frame buffer技术,所以还需要打开Console drivers中的Frame-buffer sup-port。然后,make boot就可以编译生成定制好的内核映像文件Image,将制作好的系统内核和文件系统通过宿主机的TFTP服务烧写进开发板的Flash存储器。这样就完成了板上可独立运行的操作系统的设计。
2.3 视频数据的采集、编码和传输的实现
这部分的工作是整个设计的。MPEG-4在1999年初正式成为国际标准,与之前的标准相比,它更加重视多媒体系统的交互性和灵活性,主要针对视频会议、可视电话的超低比特率编码等多媒体应用。目前在嵌入式系统中,MPEG-4编解码主要都是通过专用芯片实现的,其实现方法与MPEG-1、MPEG-2的硬件实现方法类似,将编码算法固化在芯片的硬件电路中,所以导致它在使用中存在以下缺点:
a) 性价比不高。由于现在MPEG-4编码技术还在不断发展中,还没有一个真正成熟的算法支持,所以市场上推出的MPEG-4编码芯片都是在标准基础上进行了修改和简化,在性能上与H.263等编码芯片上没有明显的优势,所以其性价比不高。
b) 可移植性差。由于各厂商所生产的编码芯片都在固化时加入了自己对编码算法的改进和优化,所以在解码端必须使用对应的专用解码器,这就导致出现了兼容性的问题。
c) 无可扩展性。随着对MPEG-4编解码标准的研究,必然提出许多新的算法及对原有算法的改进,但是现有的MPEG-4编码芯片已将已有的算法固定在了芯片硬件电路中,所以无法方便地在芯片上进行算法的修改及扩展。
所以在设计该系统时,主要采用了软件实现其编解码,在嵌入式系统中采用软件实现编解码,可以弥补硬件编解码上的诸多不足,而且便于对算法本身进行研究和改进。但是,也需要考虑几个问题:首先,由于MPEG-4编码算法运算量复杂,而嵌入式系统的资源有限,所以必须考虑所选平台微处理器的运算能力;其次,在编码软件及数据采集硬件的接口部分,由于需要针对不同的采集硬件,所以需要做许多汇编级的优化。
FFMPEG是一个音视频数据的采集记录、编码及流式传输的完全解决方案。该项目包括下面组件:
a) FFMPEG是音视频文件格式转换的命令行方式的工具,同时支持实时的采集编码TV card数据。
b) FFserver可以通过HTTP/RTSP方式进行多媒体数据的流式播放。
c) FFplayer是基于FFMPEG库和SDL的播放器。
d) libavcodec包括了全部FFMPEG音视频的编解码库,libavformat包括了全部支持的音视频格式的语法和生成库。
FFMPEG库支持的编解码支持格式非常丰富,而且编解码速度很快;支持指定音视频捕捉设备实时处理数据源并将其保存;FFMEPG能够通过命令行参数指定视频编解码、格式转换的帧频、帧大小及比特率、码率控制缓冲区的大小;并且,FFMPEG可以通过激活视频的选项来对编解码的方式进行控制,包括设置帧内编码、视频量化标度的设置、设定p帧以及b与i帧间的qp因子和偏差、运动估计及DCT/IDCT算法的选择,b帧和运动矢量以及交织编码方式的使用。对于视频捕捉设备的选择也可以通过参数来选定,如/dex/video0或DV1394专用通道等。
FFMPEG库能够在多种平台上运行,包括Linux、Windows和Mac OS等系统,在嵌入式系统中,由于嵌入式Linux具有源代码完全开放、可移植性强和对网络的支持好等特点,所以选用了ARM-Linux系统,该系统支持这次选用的ARM9架构的CPU,而FFMPEG是针对通用PC的X86架构的CPU设计的,因此要将FFMPEG移植到ARM9架构的系统上。首先需要通过将其交叉编译成可在ARM-linux上运行的库。具体步骤如下。
将的的FFMPEG源代码包解压缩再生成FFMPEG目录,然后针对所开发系统的交叉编译链,通过修改configure文件来生成Makefile文件,
然后用make命令通过读取生成的Makefile文件来自动编译生成所需要的FFMPEG库文件和可以在ARM开发板上运行的二进制可执行文件。编译成功以后就可以通过宿主机的NFS服务将宿主机安装到开发板上,这样就可以到相关目录下测试所编译的FFMPEG能否正常地工作:
2.4 视频采集编码程序的关键技术
在设计视频采集程序时主要使用FFMPEG的libavformat和libavcodec这两个函数库,许多视频文件格式一般只是定义如何将音视频流编码进一个独立的文件,而不明确指出其使用的编码工具,libavformat库的功能主要是分析视频文件的语法格式,并将它从流中分离出原始的音视频流,libavcodec库的功能则是按照流格式处理原始的音视频流编解码。
在使用libavformat/libavcodec库函数对视频文件进行处理时,首先通过调用av_register_all()函数对其初始化,这个函数中定义了所有库所能支持的文件格式和编码器,因此当读取一个文件时,通过调用此函数来自动使用所对应的格式或者编码库。视频文件打开则通过av_open_input_file函数来实现:
这样就可以读取视频流的内容来指定选用的编解码器并将编解码器打开:
这里的定义CODEC_CAP_TRUNCATED是指当视频流被分割成小的数据包以后,由于每一帧视频的数据量会发生变化,这就需要两个视频帧的边缘与数据包的边缘匹配,因此在这里定义这个宏来告诉编码器该如何处理它。调用avcodec_alloc_frame()函数来分配帧缓冲。
在编码端需要使用libavformat库函数来读取这些数据包,滤除掉不需要的非视频流数据,然后循环调用libavcodec库函数GetNextFrame(AVFormatContext *pFormatCtx,AVCodecContext * pCodecCtx,int video-Stream,AVFrame * pFrame)来处理每帧数据进行编解码。
视频采集端采用从Video4Linux视频设备源中捕捉视频帧,Video4Linux是Linux下用于获取音频和视频的API接口,现有的Video4Linux有v41和v412两个版本,我们采用v4l进行编程,在Linux下,将所有外没都看做一种特殊的文件,称之为设备文件,因此利用v4l API获取视频图像可以通过调用open、ioctl等函数,像对普通文件一样对硬件进行初始化、设置硬件属性和调用硬件中断等操作。在打开视频采集设备后,分别通过ioctl(vd->fd,VIDIOCGCAP,&(vd->ca-pability))函数的VIDIOCGCAP控制命令,来获取关于视频采集设备所能显示的图像大小,信号源的通道数和通过ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))的VIDIOCGPICT来获取一些关于图像的亮度、对比度等信息。Video4Linux方式获取视频图像的方式有overlay和mmap两种,在这里采用了MMAP方式,MMAP方式允许直接将设备内存映射到用户进程的地址空间中,这样就可以直接在进程中读写内存来控制设备。在使用libavformat/libavcodec库从Vide-o4Linux视频设备源中捕捉视频帧时需要调用av_open_input_file()函数,因此,还需要修改此函数中的设备属性配置,使之与我们所选用的没备相对应。
3 测试结果及展望
在这里使用了ffserver流媒体服务端组件来实现流媒体传输,首先需要配置ffserver.conf文件中关于服务端主机的端口号、传输带宽、延迟,流媒体文件属性等信息。然后启动ffserver读取配置文件,就可以在接收端通过WMP(Windows Media Player)输入服务端URL看到实时采集的视频图像。经测试,目前该嵌入式流媒体服务器在传输MPEG-4视频时的帧率可以达到20帧/s,接收端观察图像流畅,画面清晰。
本文提出了一种基于ARM9架构MC9328MX21的嵌入式系统上实现MPEG-4流媒体视频采集传输系统,通过在ARM-Linux操作系统下移植libavformat/libavcode库,利用该函数库良好的可移植性和Video4Linux完成了本地视频图像的采集、编码等功能,并向网络发送流媒体打包数据。该系统具有实时性好、可移植性强、低功耗和可远程移动控制嵌入式系统的特点,并且采用软件实现其主要功能,有利于系统的二次开发及升级,其应用范围和前景将非常广阔。
[1]. MC9328MX21 datasheet https://www.dzsc.com/datasheet/MC9328MX21_476203.html.
[2]. RS-232 datasheet https://www.dzsc.com/datasheet/RS-232_584855.html.
[3]. VGA datasheet https://www.dzsc.com/datasheet/VGA_2568786.html.
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。