即时串流协定(Real Time Streaming Protocol,RTSP)是用来控制声音或影像的多媒体串流协议,并允许同时多个串流需求控制,传输时所用的网络通讯协定并不在其定义的范围内,服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而前面提到的允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,更进而支持多方视频会议(Video Conference)。
基于以太网的嵌入式视频监控得到越来越广泛的应用,如通过3G网络传给服务器,将移动机器人所采集到的视频数据通过3G网络传给服务器。流媒体技术也在不断的普及,将目前流行的流媒体传输技术应用到视频监控系统中是比较好的选择,既不会占用太多的网络带宽,也可以实现较为流畅视频监控。本文基于H264编码技术和对Live555二次开发,设计了一种可对柑橘生长进行视频实时采集,编码,传输的嵌入式流媒体视频监控系统。
1 网络监控视频技术简介
RTSP(Real Time Streaming Protocol),即实时流传输协议,属于TCP/IP协议体系顾名思义,它是一个用于流媒体传输控制的协议,能够控制流媒体在传输过程中的暂停与继续,从而方便用户实现播放器的一些基本播放功能。它也以C/S方式(客户端服务器)工作,由于结合了很多技术上的优点,目前在因特网视频应用中广泛流行。
图1 RTSP与RTP、RTCP关系
RTSP协议与RTP(Real Time Protocol)协议、RTCP(Real Time Control Protocol)的关系如图1所示,通常而言,RTSP只用来传输控制信息,这些控制信息使得媒体播放器能控制流媒体的传输,而流媒体的传输则由RTP负责,所以RTSP协议必须与RTP/RTCP协议一起配合使用。
1.2 H.264技术
H.264技术是目前在视频编码压缩中采用的最为普遍的一种技术。由于H.264具有更低的码率,在同等图像质量的前提下,它可以达到更高的压缩率,与前代MPEG-2相比,压缩比通常是它的2倍以上;H.264在算法方面更加复杂,所以它相比上代压缩技术也能够提供高质量的图像。而且它的容错能力也很强,网络适应能力非常好。在本设计中,对于动态变化不是很明显的视频,H.264显示出了非常强大的压缩能力,使得网络带宽大大减少。本设计只采用了H.264的编码部分,应用目前最为流行的符合H.264规范的x264工程作为编码器。
1.3 Live555开源工程
Live555是一个开源项目,使用C++语言编译,为RTSP、RTP/RTCP、SIP等标准流媒体传输协议提供解决方案,支持目前主流的ts、mpg、mkv、h264格式的视频,被大多数流媒体服务器应用为开发平台,VLC、ffplay等多款播放器能够点播使用Live555作为流媒体服务器的视频数据。Live555有四个基本的库,即BasicUsageEnvironment、UsageEnvironment、GroupSock和LiveMedia。前面三个库在本设计中均不需要改动,需要改动的是LiveMedia模块,它是Live555最重要的模块。这个模块的主要作用是声明一个Medium类,在Live555工程中,很多其他类都是它的派生类。
1.4 YUV图像数据分析
常用的YUV元素图像格式有YUV422格式和YUV420格式。YUV422格式中,按照U、V在时空上的排列顺序不同,可以将他们分为YUYV,YVYU,UYVY,VYUY四种不同的排列方式,目前大部分USB摄像头输出的原始图像都是按照YUYV格式来排列的;按Y和UV的排列方式不同又可以分为打包格式和平面格式,打包格式通常以英文字母planner表示,而平面格式则会用interlaced表示,打包格式较为常见,它的Y分量和UV分量在内存中是连续放置的,如图2右侧的示意图所示,而平面格式Y和UV分量则是分开放置的,如图2左侧示意图所示。
图2 YUV排列格式示意图
YUV420在排列上和YUV422规律相同,但是Y:U:V是4:1:1的。一般情况下,利用V4L2采集USB摄像头的视频数据是YUYV交错排列的打包YUV422格式的,但是H264编码库要求输入的视频格式是YUV420P,也即4:1:1的平面格式,所以要经过转换。本设计采用成熟的libswscale库来转换原始图像数据。
2 流媒体服务器的实现
2.1 系统整体结构
本设计参考目前流行的视频监控系统,基于Linux的平台,利用V4L2(Video for Linux Two)函数接口,采集USB摄像头传过来的数据,因目前一般的USB摄像头只支持YUYV排列的YUV422格式的数据采集,因此需要将采集到的数据格式转换为YUV420P之后,再利用x264对每一帧YUV数据进行编码,最后对Live555开源工程进行二次开发,构建流媒体服务器。本设计系统总框图如图3所示。
图3 系统架构图
在本设计中,系统平台为Linux,USB摄像头的型号为环宇飞扬v8,只支持输出YUYV排列的YUV422格式的图像数据,x264目前只支持YUV420P的图像数据输入,因此为了保证稳定可靠,采用FFmpeg工程中的libswscale对其进行数据格式转换,最后利用构建好的RTSP服务器对编码的数据进行实时发送传输。
2.2 构建流媒体服务器
对于不同的流媒体源,其数据排列格式不同,因而获取SDP的方法不同。在构建新的流媒体源的基础上,需要对SDP获取部分代码进行二次开发。因此,本设计的工作分为下面两部分。
2.2.1 SDP获取代码二次开发
当RTSPServer收到对某个媒体的DESCRIBE请求时,它会找到对应的ServerMediaSession,调用ServerMediaSession::generateSDPDescription()。generateSDPDescription()中会遍历调用ServerMediaSession中所有的调用ServerMediaSubsession,通过subsession-》sdpLines()取得每个Subsession的sdp,合并成一个完整的SDP返回之。对于不同流媒体格式获取SDP信息的方式不同,因此,本设计基于OnDemandServerMediaSubsession类构建新的会话类WebcamOndemandMediaSubsession。
图4 获取SDP函数调用关系图
获取SDP信息的函数调用关系如图4所示,sdpLines()函数在OnDemandServerMediaSubsession类中已经实现,为了顺利的获取SDP信息,我们需要对sdpLines()运行时调用的几个函数作一定的修改,因此,需要对OnDemandServerMediaSubsession类中的几个虚函数进行重载,具体做法如下:
A、对于createNewStreamSource函数,因为本设计处理的是H264格式的源,函数中应当加入H264VideoStreamFramer::createNew()语句。
B、对于createNewRTPSink函数,同理,函数中应当加入H264VideoRTPSink::createNew()语句。
C、setSDPLinesFromRTPSink取得Subsession的sdp并保存到fSDPLines,这个函数重点是调用getAuxSDPLine,因此需要重构getAuxSDPLine函数。getAuxSDPLine函数所调用的chkForAuxSDPLine也需要重载。对于H.264文件,是不能从rtpSink中取得PPS/SPS的,所以必须调用startPlaying函数对视频流播放一下才行,播放之后又会关闭,这点在建立连接的时候可以用打印函数调用流程以便了解的更加清楚。在下面的伪代码中,可以看到之后又调用了chkForAuxSDPLine这个函数,这是为了保证在函数退出前能正确取得AuxSDP,所以在chkForAuxSDPLine函数中需要循环检查是否取得AuxSDP。伪代码如下所示。
rtpsink = sink;
rtpsink-》startPlaying(*source, 0, 0);// 开始播放
chkForAuxSDPLine(this); // 循环检查
sdp_line = strdup(rtpsink-》auxSDPLine());//保存
mp_dummy_rtpsink-》stopPlaying(); // 停止播放
return mp_sdp_line; // 返回值
2.2.2 构建WebcamFrameSource类
WebcamFrameSource属于一个source类,也就是一个能够提供视频源的类。流媒体开发大都具有相似的特征,Live555中也继承了source和sink的精神,简而言之,Source就是产生数据的对象,而Sink节点是数据最终流向的对象,Sink的数据必须通过source读取。Live555工程中虽然已经实现好众多的source,但是并没有能够实现直播摄像头过来的数据的功能,因此,二次开发的主要任务之一便是构建新的source,该source应该具有将H264的打包数据存放在内存中,并且能够传送给H264VideoRTPSink。本设计中,基于FramedSource构建WebcamFrameSource类。
对于WebcamFrameSource类,主要开发工作是在其构造函数中配置好V4L2采集摄像头数据,x264编码优化设置,作为一个source类,每次从该source中取数据时,都会调用doGetNextFrame函数,该函数作为FramedSource类中的一个虚函数,可以在新构造的WebcamFrameSource类中进行重载。对V4L2设备的初始化流程如图5所示。
图5 V4L2初始化设置
X264视频编码初始配置伪代码如下所示。
ctx-》force_keyframe = 0; // 不使用强制关键帧
x264_param_default_preset(ctx-》param, fast, zerolatency); //预设为零延迟
ctx-》param.b_repeat_headers = 1;
ctx-》param.b_cabac = 1; //支持cabac
ctx-》param.i_threads = 1; //缓冲区数据被取完后任使用不会出现死锁
ctx-》param.i_fps_num = 30; // 帧率为30
ctx-》param.rc.i_bitrate = 150; // 默认码率
ctx-》x264 = x264_encoder_open(ctx-》param); // 使用设置好的参数打开编码
x264_picture_init(ctx-》picture); // 输出图像初始化
另外,也需要对libswscale的使用做一定的初始化,在本设计中,libswscale主要用来转换V4L2输出的yuv422格式数据为YUV420,其中主要是配置图像高度,宽度,输入输出格式,涉及到的函数主要是sws_getContext和avpicture_alloc,在此不再做详细叙述。
在从WebcamFrameSource这个流媒体源中取数据时,都会调用doGetNextFrame这个函数,此函数是FramedSource类中定义的虚函数,因此需要在构建WebcamFrameSource类时进行重载。从流媒体服务器发出一帧数据的流程如图6所示。
图6 数据传输流程图
按照流程图构造新的流媒体源,并且根据帧率设置读取两帧的间隔延迟时间,能够满足实时性要求。
3 系统实现
3.1 软硬件环境
服务器硬件环境为TI的DM3730处理器,256MB运行内存,该处理器基于Cortex-A8架构,主频为1GHz,并采用比较通用的环宇飞扬V8的USB摄像头。软件方面,基于Linux 2.3.32内核,并装载Angstrom文件系统。
客户端为普通PC,运行Ubuntu 10.04,客户端连接程序使用FFmpeg项目中的ffplay,该播放器能够很好的支持RTSP点播。
3.2 移植要点
本设计中需要编译的库文件为x264,以及libswscale,V4L2已经包含在Linux内核驱动中,x264可以下载到单独的工程,而libswscale包含在FFmpeg工程中。
对于x264工程的编译,本设计直接从x264官网下载版本号为20140104-2245的源码,使用如下命令配置。
。/configure --prefix=/home/x264 --enable-shared --enable-static --enable-debug --cross-prefix=arm-none-linux-gnueabi- --host=arm-linux
命令的含义大致为安装目录为/home/x264,同时编译静态和动态库文件,使能调试,并设置好交差编译工具链。配置好后使用make;make install即可得到编译好的目标板文件。然后将x264.h和x264_config.h复制到目标板的/usr/include目录,库文件复制到/usr/lib目录。
要获取libswscale,需要先编译FFmpeg,本设计采用的FFmpeg版本号为0.8.15,配置FFmpeg的命令如下所示。
。/configure --prefix=/home/FFmpeginstall/ --enable-shared --target-os=linux --enable-cross-compile --cross-prefix=arm-none-linux-gnueabi- --arch=arm
配置好之后,使用make;make install命令,将安装目录下include中libswscale目录复制到目标板的/usr/include目录,lib目录中的libswscale.a和libswscale.so复制到/usr/lib目录。
然后再使用交叉编译工具利用刚才编译好的这些库文件,编译目标板可执行的流媒体服务器主程序,编译好之后将可执行程序拷贝到目标板的/opt目录下。
3.3 优化
由于运行环境为嵌入式系统,资源有限,而且又要保证流播放的实时性,因此需要做一些调整。本设计中程序运行负担主要集中在编码部分,为了减轻编码负担,使用libswscale将分辨率为640x480的视频流转换为320x240大小的视频流。在视频传输过程中,降低帧率,最终确定为15帧的帧率。为了保证实时性,对x264编码参数预设为快速,零延迟。
3.4 系统测试运行
当服务器开启之后,客户端PC通过以太网与目标板连接,设置客户端PC网卡地址,确保在同一IP网段上面,在客户端给ffplay传入RTSP://192.168.71.128:9554/webcam参数。
结语
在当下RTSP技术被普遍应用的背景下,本文构建了一个结合实时视频采集、编码和嵌入式技术的RTSP流媒体服务器,并采用目前常用的支持RTSP技术的FFplayer作为客户端播放器,实现了嵌入式视频监控系统的设计,整个系统成本低廉,稳定可靠,并且负荷方面基本能满足中小型应用的要求,具备一定的参考价值。
评论
查看更多