程雷阳
(北京中电慧视科技有限公司,北京 100015)
乘客信息系统(Passenger Information System,PIS)是地铁列车为乘客提供到站等广播服务和新闻、娱乐等各种资讯的综合性信息系统,在火灾、紧急疏散等突发情况下,系统可以提供紧急通知,因此也被称为车载多媒体信息系统。随着网络和数字多媒体技术的发展,车载多媒体信息系统也逐渐要走向高清化、数字化,同时也引入了地面数字直播视频源来满足乘客对实时资讯的需求[1]。基于此,本文提出了一种基于瑞芯微平台的车载高清流媒体客户端的设计方案,并成功进行了相关测试。播放系统由流传输设施和解码终端组成,前端流媒体发送采用模拟视频流服务器的形式,播放终端与媒体服务器之间通过以太网相连,本文主要考虑在IP层的广泛应用上,结合有线的数据链路层特点,采用RTP/RTCP流媒体协议在UDP传输层进行传输[2]。流媒体终端设备能够充分满足车载工作要求,系统功能稳定性良好。软件程序启动速度快并且支持多协议,视频播放流畅,音频无杂音存在,音视频同步功能较好。这款跨平台的嵌入式流媒体播放系统可以很好地实现车载视频播放功能。
瑞芯微公司提供的媒体处理软件平台(Media Process Platform,MPP)是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理,屏蔽不同芯片的差异,为使用者提供统一的视频媒体处理接口(Media Process Interface,MPI)。
MPP提供了视频解码功能,解码类型涵盖了H.265/H.264/H.263/VP9/VP8/MPEG4/MPEG2/MPEG1/VC1/MJPEG,视频编码功能支持H.264/VP8/MJPEG,同时也提供了多种视频处理功能,如视频拷贝、缩放、色彩空间转换以及场视频解交织等。平台系统框架的层次如图1所示.
图1 MPP系统框架
硬件层是瑞芯微系列芯片平台的视频编解码硬件加速模块,包括VPU,rkvdec,rkvenc等不同类型、不同功能的硬件加速器。
内核驱动层包含Linux内核的编码器硬件设备驱动以及相关的内存管理单元、内存、时钟、电源管理模块等,支持的平台主要是Linux kernel 3.10和4.4两个版本。MPP库对于内核驱动有依赖。
用户态的MPP层屏蔽了不同操作系统和不同芯片平台的差异,为上层使用者提供统一的MPI接口。MPP层包括MPI模块、OSAL模块、HAL模块以及视频编解码器Video Decoder/Video Encoder和视频处理功能模块(Video Process)。
操作系统层是MPP用户态的运行平台,如Android以及Debian等Linux发行版。本文最终应用的实现基于Debian的发行版。
MPP层通过MPI对接各种中间件软件,可以采用的中间件软件有OpenMax,ffmpeg和gstreamer。如果使用开源的FFmpeg库解码解封装获得流式数据,基于Qt应用程序中的OpenGL库显示平面视频帧数[3]。gstreamer中的playbin2元件可以节省开发人员的精力,进一步缩短产品的开发周期,如所用的解码器支持多种格式的解码,就可以增加产品对多媒体类型的支持[4]。本文最终实现采用的中间件软件为gstreamer。
由于视频编解码与视频处理过程需要处理大量的数据交互,包括码流数据、图像数据以及内存数据,同时还要处理与上层应用以及内核驱动的交叉关系,所以MPP设计了MPI接口,用于与上层交互。MPI接口使用的主要数据结构如图2所示。
图2 MPI接口数据结构
MppPacket为一维缓存封装,可以从MppMem和MppBuffer生成,主要用于表示码流数据。MppFrame为二维帧数据封装,可以从MppMem和MppBuffer生成,主要用于表示图像数据。使用MppPacket和MppFrame,就可以简单有效地完成一般的视频编解码工作。以视频解码为例,码流输入端把地址和大小赋值给MppPacket,通过put_packet接口输入,在输出端通过get_frame接口得到输入图像MppFrame,即可完成最简单的视频解码过程,部分伪代码如图3和图4所示。
图4 视频流输出显示
MPI(Media Process Interface)是 MPP提供给用户的接口,用于提供硬件编解码功能以及一些必要的相关功能。MPI通过C结构里的函数指针方式提供给用户。用户可以通过MPP上下文结构MppCtx与MPI接口结构MppApi组合使用来实现解码器与编码器的功能。用户可以通mpp_create接口获取MppCtx实例以及MppApi结构体,再通过mpp_init来初始化MppCtx的编解码类型与格式之后通过decode_xxx/encode_xxx以及poll/dequeuer/enqueue接口进行访问,使用结束时通过mpp_destroy接口进行销毁,过程如图5所示。
图5 MPI相关函数
gstreamer是一个用于开发流媒体应用的开源框架,采用了基于插件(plugin)和管道(pipeline)的体系结构。框架中所有的功能模块都被实现成可以插拔的组件(component),并且能很方便地安装到任意一个管道上。rockchipmpp是瑞芯微公司开发的一个gstreamer插件,主要是为了把自己的MPP与gstreamer结合起来。使用者基于gstreamer开发一个应用程序时,使用gst/gst.h即可访问库文件中的函数。除此之外,还需要初始化gstreamer library。本文使用gst_init初始化,它的主要功能如下:
(1)初始化gstreamer库;
(2)注册内部Element;
(3)加载插件列表,扫描列表中及相应路径下的插件;
(4)解析并执行命令行参数。
构建了所有必需的gstreamer插件之后,需要借助gstreamer来构建从Debian基于Qt环境的媒体播放器组件VideoView的接口,利用MPP框架提供媒体处理服务。在这些步骤中,可以使用gstreamer框架中的一些低级别元素来构建媒体播放器,不过采用这种方法相对复杂。例如,针对一个特定的剪辑视频,首先要分析它属于哪种视频容器格式,然后根据不同的视频容器格式,使用不同的解码元素,并且需要连接传输管道中所涉及的基本元素,这样才能使得整个视频处理步骤运行起来。由于不同的视频剪辑对应不同的处理元素,为了保证实用性和稳定性,本文使用gstreamer的高级别元素“Playbin2”来启动传输管道,之后,添加条总线到Playbin2,让视频数据和视频处理事件流入总线,最后启动传输管道和总线[5]。
RK3568是一款定位中高端的通用型系统级芯片,采用22 nm先进制程工艺,主要面向工业互联网、HMI、NVR存储、车载中控以及工业网关等领域。CPU采用四核64位Cortex-A55,主频最高2.0 GHz,是一款非常优秀的通用型SoC。同时,RK3568内嵌高性能2D加速硬件,可支持JPEG硬解码、双网口、三屏异显以及多PCIESATA接口,本身集成神经网络处理器(Neural-network Processing Unit,NPU),其特性在图片处理、存储、通信、多功能外设等应用场景可发挥独特的优势。
操作系统软件平台采用Debian 10,集成开发环境采用Qtcreator,采用Qt图形界面的方式来实现,Qt层面调用瑞芯微提供的gstreamer的插件rockchipmpp,前端流媒体数据发送采用使用WinSend发送UDP组播流,组播流地址为UDP://239.1.1.1:8208,如图6所示。
图6 测试发送UDP组播TS视频流
首先使用WinSend模拟发送2 Mb·s-1的TS码流,测试终端播放状态。播放状态如图7所示。
图7 2 Mb·s-1的TS流媒体解码效果
使用WinSend模拟发送4 Mb·s-1的TS码流,测试终端播放状态。播放状态如图8所示。
图8 4 Mb·s-1的TS流媒体解码效果
两种状态均采用硬解码实现,CPU占用率为32%。实际测试有较多性能富余,可用于处理其他业务逻辑。实际CPU占用率如图9所示。
图9 硬解码CPU占用率
本文基于瑞芯微RK3568平台,使用平台提供的MPP框架,同时采用gstreamer插件的形式对MPP框架视频硬解码接口进行实现和调用,实现了车载流媒体的硬解码方案,实测解码达到设计的预期效果,CPU占用率较低,可以有富余的资源处理其他业务逻辑,实测解码显示效果良好、稳定,满足轨道交通车载媒体系统的使用需求。