基于ARM的嵌入式网络视频监控系统的设计与实现
方卫民1,孙百生2,李娜1
1北京邮电大学自动化学院,北京 (100876)
2北京信息科技大学,北京 (100085)
E-mail:fwm2008@tom
摘要:本文设计了一种基于嵌入式linux的网络视频监控系统。针对mjpeg流的多媒体数据实时传输要求,设计并实现了在Arm-linux平台下基于JRTPLIB库的RTP/RTCP传输协议的流媒体实时传输。简要介绍了系统的软、硬件平台;重点阐述了基于USB摄像头的视频采集和视频数据的传输的过程,对其中的若干关键技术进行了较为详细的介绍。
关键词: 嵌入式,视频监控,S3C2410,JRTPLIB,RTP/RTCP
1. 引言
视频监控以其直观、方便、信息内容丰富而广泛应用于许多场合,已经渗透到交通、城市治安、国防等多种领域,在人们的日常生活中扮演着越来越重要的作用。从视频监控系统的发展来看,传统的视频监控系统主要是采用本地模拟信号监控和基于PC的多媒体监控这两种模式。这两种监控系统存在的主要缺点在:结构复杂、稳定性和可靠性不高、价格昂贵而且传输距离明显受限。
随着网络技术、信息技术和计算机技术的飞速发展,视频监控系统的发展趋势必然是全面数字化、网络化,加上现在微处理器性能的大大提高,基于嵌入式网络视频监控技术应用而生,它的主要原理是:嵌入式服务端采用微处理器和嵌入式操作系统,结合网络技术,将采集来的视频图像经过压缩处理,传输到网络,实现网络视频监控。嵌入式视频监控系统以其小巧、灵活、低成本、性能稳定、高性能的特点而独具优势,结合TCP/IP,通过建立Client/Server工作模型来实现网络视频监控[1]。
本文针对视频监控设备的实际应用需求,结合嵌入式系统、图像采集和网络技术,设计了以ARM微处理器作为硬件平台、以具有功能强大、免费以及开发资源丰富等优势的linux 作为软件开发平台的嵌入式网络视频监控系统,并实现了视频数据的采集、网络传输、显示和保存。
2. 监控系统中的硬件系统框图
本文设计的系统整体框图如图一所示。本系统核心处理器采用ARM9芯片S3C2410X,它是16/32位RISC嵌人式微处理,它采用了ARM920T核、5级流水线,内部带有全性能的MMU,具有指令和数据Ca
che,内核运行速度高达203MHz,具有高性能、低功耗、接口丰富和体积小等优良特性。本系统根据设计要求集成了64 MByte的SDRAM和64 MByte的NAND Flash、10/100 MByte的以太网接口、RS-232接口、实时时钟及USB主控接口以及
ZC301P CMOS感光USB摄像头。
Flash采用K29F2808,它是一款64M Byte的NAND型Flash,本系统中启动代码、内核代码及根文件系统都存放于此。考虑到系统运行的流畅性,RAM是2片32M的HY57V561620的SDARM,这样就可流畅地运行Linux及网络应用。网络控制芯片采用AX88796以太网控制器,通信速率为10/100M自适应,通过它可实现以太网的物理层和数据链路层。而USB CMOS摄像头有着良好的性能、低廉的价格、灵活、方便易于集成到嵌入式系统的特性。系统中选用了中星微的ZC301P CMOS感光USB摄像头,每秒钟可输出30帧图像,支持的最高分辨率为
640X480dpi,输出数据已经jpeg压缩处理,数据量大大减少,不用再经过软件压缩处理可以节省硬件系统资源,这点对资源宝贵的嵌入式系统来说尤为重要。
3. 监控系统中的软件系统
嵌入式系统软件平台的构建主要工作有:嵌入式操作系统内核的裁剪与移植、Bootloader 的移植、根文件系统的制作。
由于linux操作系统具有内核小、效率高、源代码开放、免费以及开发资源丰富等优势。而且针对具体的应用,通过配置内核、裁剪shell和嵌入式C库对系统定制都极为方便,使整个系统能够存放在容量较小的flash中[2]。正因为上述的一些优点,在本文实现的平台上选用Linux.2.4.18-rmk7作内核。它是在Linux 2.4.18内核的基础上通过裁剪得到的可移植到ARM上的Linux内核;在文件系统上,首先采用针对嵌人式系统设计的YAFFS文件系统;根文件系统选择了cramfs文件系统;Bootloader选用的是韩国MIZI公司的VIVI。
(关于嵌入式软件系统平台的搭建的具体情况请查阅[3]和[4])
4. 网络视频监控的具体实现
在Arm-linux嵌入式系统上,视频服务程序不断采集摄像头获取的实时视频画面,通过基于JRTPLIB的RTP/RTCP协议发往网络客户端,从而实现对网络现场的实时监控。本视频监控系统的实现主要分以下三步来实现:1、为USB口数码摄像头在内核中写入驱动;2、在平台上编写上层应用程序获取视频数据,
通过网络传输到客户端;3、编写客户端应用程序通过网络获取视频数据显示出来。本文主要讨论第1步和第2步。
4.1 USB 摄像头驱动的安装
在Linux下,设备驱动程序可以看成Linux内核与外部设备之间的接口。设备驱动程序向应用程序屏蔽了硬件实现了的细节,使得应用程序可以像操作普通文件一样来操作外部设备,可以使用和操作文件中相同的、标准的系统调用接口函数来完成对硬件设备的打开、关闭、读写和I/O控制操作,而驱动程序的主要任务也就是要实现这些系统调用函数。本系统平台使用的嵌入式Arm-Linux系统在内核主要功能上与Linux操作系统没本质区别,驱动程
序要实现的任务也一样,只是编译时使用的编译器、部分头文件和库文件等需要涉及到具体处理器体系结构[5]。
前已提到,本系统选择的USB摄像头是中星微的ZC301P。选择usb-2.4.31LE06.patch.tar 作为ZC301P摄像头驱动,该驱动是专门针对嵌入式系统作了优化,需要更少的内存以节省嵌入式系统资源。驱动可以在mxhaard.free.fr下载。
把usb-2.4.31LE06.patch.tar拷贝到宿主机的嵌入式内核的drivers/usb下,然后依次执行:tar –  xzvf usb-2.4.31LE06.patch.tar
patch –p1 < usb-2.4.31LE06.patch
解压并打补丁后,将usb/spca5xx文件夹下j和j文件中带有“+”部分的内容分别添加到Makefile和Config.in中。
进入嵌入式系统内核目录,执行make menuconfig,V4l项、usb for support和spca5xx项都选为(*),保存推出。再依次执行make dep,make zImage,加载新内核zImage,启动新内核,这样新内核在启动后就能支持USB摄像头了。摄像头正常工作后,接着进行下一步:视频数据采集编程。
4.2 视频数据采集
在linux下进行视频采集,都是通过调用Video4Llinux(简称v4l)的API函数实现采集摄像头视频数据的。V4l是Linux中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供一系列接口函数。对于USB口摄像头,其驱动程序中需要提供基本的I/O操作接口函数open、read、write、close的实现,对中断的处理实现,内存映射功能以及对I/O通道的控制接口函数ioct1的实现等,并把它们定义在struct file_operations中。这样当应用程序对设备文件进行诸如open等系统调用操作时,Linux内核将通过file_operations结构访问驱动程序提供的函数[6]。
4.2.1 v4l常用数据结构及其作用
(1)  video_capability 设备基本信息:设备名称、最大最小分辨率、信号源信息等。
(2) video_picture    设备采集的图象的各种属性:如颜、对比度、亮度等。
(3) video_channel    各个信号源的属性:如信号源编号、名字、制式等。
(4) video-window    关于capture area的信息
(5) video_mbuf      利用mmap进行映射的帧的信息:每帧大小,最多支持的帧数、每帧相对基址的偏移等。
(6) video-mmap 用于内存映射
mmap格式怎么打开
4.2.2 视频编程的流程
截取视频图象有两种方法:a.直接读取(read());b.内存映射(mmap())。read()通过内核缓冲区来读取数据;而mmap()通过把设备文件映射到内存中,绕过了内核缓冲区,最快的磁盘访问往往还是慢于最慢的内存访问,所以mmap()方式加速了I/O访问。另外,mmap()系统调用使得进程之间通过映射同一文件实
现共享内存,各进程可以像访问普通内存一样对文件进行访问,访问时只需要使用指针而不用调用文件操作函数,这样进程可以直接读写内存,而不需要任何数据的拷贝,mmap()方式显而易见的好处是效率高。因为mmap()的以上优点,所以在程序实现中采用了mmap()方式来读取视频图像。mmap函数返回的地址就是存放图像数据的地址,摄像头取得图像会包含若干帧,每一帧图像都相对此地址偏移固定的长度。
这样通过周而复始的进行就可以将图像数据捕获下来[6]。(关于ioctl()函数具体用法,可以参考参考文献[7]),视频采集的流程图如图二所示:
这样,图像数据就存放在memorybuf+videombuf.offsets[vmmap.frame],接下来的工作就是将视频数据网络传输到客户端。
4.3 视频数据的网络传输和接收
4.3.1 RTP/RTCP传输协议
对于视频监控来说,实时性要求要高于可靠性,而且视频数据具有数据量大、允许有一定误码率等特点,对压缩后的MJPEG视频流采用高效率的UDP协议传输;同时为了保证可靠的传输质量,网络传输部分采用了实时传输协议RTP/RTCP,该协议建立在传统的TCP/IP 协议之上,能够提供流媒体数据高效率传输,同时亦对多方用户连接建立、网络状况实时侦测、用户管理、网络异常处理等有很好的支持。。
RTP(Real-timeTransportProtocol)是用于internet上针对多媒体数据流的一种传输协议。
RTP被定义为在一对一或一对多的传输情况下工作,其目的是提供时间信息和实现流同步。当应用程序开始一个RTP会话时将用两个端口:一个给RTP,一个给RTCP。RTP本身并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP (Real-timeTransportControlProto
col)提供这些服务。RTCP和RTP一起提供流量控制和拥塞控制服务。在RTP会话期间,各参与者周期性地传送RTCP包。RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据[8]。
RTP/RTCP是目前解决流媒体实时传输问题的最好办法,要在 Linux 平台上进行实时传送编程,可以考虑使用一些开放源代码的 RTP 库,如 LIBRTP、JRTPLIB 等。
4.3.2 JRTPLIB库
JRTPLIB 是一个的面向对象的 RTP 库,它完全遵循 RFC 1889 设计。JRTPLIB 是一个用 C++ 语言实现的 RTP 库,因此这个库在安装编译时候要选用arm-linux-g++作为编译器。
JRTPLIB 是一个高度封装后的RTP库,程序员在使用它时很多时候并不用关心RTCP 数据报是如何被发送和接收的,因为这些都可以由JRTPLIB自己来完成。只要 PollData()或者SendPacket()方法被成功调用,JRTPLIB就能够自动对到达的RTCP数据报进行处理,并且还会在需要的时候发送 RTCP数据报,从而能够确保整个RTP会话过程的正确性[9]。
4.3.3 多播
IP多播技术(Multicast,也称多址广播或组播),是一种允许一台或多台主机(多播源)发送单一数据包到多台主机(一次的,同时的)的TCP/IP网络技术。多播在发送数据时将数据流发往某个多播地址(一个D类地址),每个多播地址代表一个多播组。接收方加入这个多播组,就可接收发往该组的数据。多播作为一点对多点的通信,减少了不必要的重盛发送,可有效提高网络带宽的利用率和视频数据的实时性,是节省网络带宽的有效方法之一。而且JRTPLIB也支持多播传输,在该系统中选用了多播的传输方式。
4.3.4 基于JRTPLIB库多播的流媒体编程
在使用 JRTPLIB 进行实时流媒体数据传输之前,首先应该生 RTPSession 类的一个实例(RTPSession sess;)来表示此次 RTP 会话。在设置Server端的时候,与TCP/IP协议不一样,首先在初始化打开的Session的时候,设置一个base port,同时设置Client端的IP和port,然后再根据视频采样的频率设置时间戳。
下面给出server端和client端的RTP/RTCP发送和接收数据流程框图。

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