视传机实现这些功能基本原理就是用MiniGUI制作图形界面进行人机交互[1],用户通过键盘或者遥控器进行指令输入,MiniGUI接收用户指令,并传给操作系统(这里我们使用Linux 2.6.19),操作系统根据指令的不同进行不同的操作,例如若用户想进行视频呼叫,操作系统就将指令发给Linphone,Linphone就在SIP协议的基础上发起视频呼叫,根据对方不同的状态给出不同的响应,对方不在线、对方忙、对方正常应答等,在正常应答的情况下双方协商音频视频通信编解码方式,建立呼叫,进行音视频通信[2],然后任意一方挂机,退出,完成一次通信,期间还可以进行音视频录制等操作。再如若用户想进行电影播放,则操作系统会调出播放程序,播放用户指定的电影文件。
视频流的流程如下:由摄像头(支持自带插针式和TV输出两种)采集图像数据,交给操作系统[3],操作系统根据用户需要,将视频数据进行本地显示、编码录制或者发送到对端,对端收到视频数据送入VPU单元进行解码,然后显示或者录制等。通话过程中音频流的流程为:通过mic采集音频数据,交给操作系统,操作系统将数据送给Linphone,Linphone进行一定格式的编码[4],然后发送到对端,对端再进行相应的解码,再将数据输出到音箱或者耳机。
视传机主要软件Linphone的移植
Linphone有很多个版本,可以通过www.linphone.org免费下载。我们这里使用带视频功能的linphone1.6.0版本,要将这个Linphone使用在开发板上,需要做3个方面的工作:添加H264硬件视频编解码器(使用i.MX27的VPU单元进行视频编解码),修改程序使之与操作系统和其他应用程序进行通信,最后交叉编译Linphone至开发板。
Linphone功能结构
Linphone1.6.0版本的功能结构如图1。
console包括了整个终端界面部分,将界面操作和命令行输入交由下层处理。
coreapi包含Linphone大部分核心接口函数,如读配置文件进行程序初始化、呼叫的建立和结束、对SDP消息的处理等。
osip2是一个短小简洁的sip协议栈,专注于sip底层解析。
exosip是osip2的一个扩展协议集,它部分封装了osip2协议栈,使得它更容易被使用。
mediastreamer模块负责语音及铃音等的处理及传输,视频的编解码(调用ffmpeg的库)、声卡的选择等。
ortp将音视频打包为rtp包发送至指定端口。
speex是一种音频解码库。
添加H264硬件视频编解码器
Linphone1.6.0 本身具有视频编解码功能,默认具有H263 、mpeg4、mjpeg等编解码器,我们要仿照这些编解码器的源码结构添加H264解码器,重要的是将编解码器的软件编解码部分替换成i.MX27的 VPU(视频处理单元)来进行硬件编解码,因为i.MX27的CPU处理速度有限,远及不上PC的CPU,而i.MX27的VPU则是专门进行视频编解码处理的协处理器,在处理视频数据的时候是不需要CPU参与。
代码的添加过程如下:在向Linphone注册编解码器的地方添加H264编解码器,使得Linphone具备H264编解码器的功能选项,注册的内容包括:编解码器id,一些名称文本等标识符,编解码器初始化,视频数据预处理、处理、后处理,编解码器销毁(释放系统资源)等函数链接,编解码器方法(进行基本视频编解码处理之外的操作)等。注册好编解码器后,就是如何真正实现编解码器对视频流的编解码处理了,也就是编解码器的初始化,视频数据预处理、处理、后处理,编解码器销毁等函数的实现。视频处理的软件部分主要包括内核空间的驱动和编解码库以及用户空间的应用程序。内核驱动负责系统控制和系统资源的申请和释放,提供一些IOCTRL接口给用户空间的应用程序使用调配系统硬件资源;用户空间的应用程序调用适当的IOCTRL和编解码库函数来实现复杂的编解码系统。