《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 设计应用 > 基于Mplayer的嵌入式流媒体播放器的设计与实现
基于Mplayer的嵌入式流媒体播放器的设计与实现
2014年电子技术应用第10期
闻连臣,段晓辉,郭跃超,张 振
北京大学 无线通信与信号处理研究中心,北京100871
摘要: 基于开源播放器Mplayer和嵌入式处理器S3C6410,通过移植开源流媒体协议库live555,并将S3C6410的硬件解码器MFC加入到Mplayer的解码库中,设计实现了一款硬件解码视频的嵌入式流媒体播放器。
中图分类号: TP31
文献标识码: A
文章编号: 0258-7998(2014)10-0009-03
Design and implementation of embedded streaming media player based on Mplayer
Wen Lianchen,Duan Xiaohui,Guo Yuechao,Zhang Zhen
Wireless Communications and Signal Processing Research Centre,Peking University,Beijing 100871,China
Abstract: Based on the open-source player Mplayer and embedded processor S3C6410, by transplanting the open media library live555, and adding the hardware decoder of S3C6410 which is called MFC to the decoding library of Mplayer, this article designs and implements an embedded streaming media player which based on hardware decoding video.
Key words : Mplayer;embedded;hardware decoding;streaming media

0 引言

    多媒体的呈现方式从本地播放、下载存储播放逐步发展到流式播放[1]流媒体融合了网络和多媒体编解码等技术,虽然在PC 领域上的应用已比较成熟,但是在嵌入式领域,仍有着很大的开发空间。文中提到的向Mplayer的解码库中添加S3C6410的多媒体编解码模块MFC(multi format codec)[2],具有很强的应用价值。

    本设计的平台是HINOC手持测试仪。HINOC[3](High performance Network Over Coax)是“三网融合”中的从光纤网到用户的一个传输方案,如图1所示。头端设备(HINOC Brige,HB)对多个终端设备(HINOC Modem,HM)进行管理。

qrs1-t1.gif

    HINOC 手持测试仪的主要功能是不仅有 HM的功能,还能协助工程人员进行故障定位。图2和图3显示了其硬件和软件结构。

qrs1-t2.gif  

qrs1-t3.gif

    工作人员通过流式传输可以观看远程业务视频,而且能直观地验证网络的底层是否连通。

1 需求分析

    本系统采用了ARM-Linux,处理器是基于ARM1176JZF-S的S3C6410,播放器是Linux系统上最优秀的播放器之一Mplayer[4],结构如图4所示。将S3C6410的MFC加入Mplayer的解码库中,通过移植协议栈live555,Mplayer支持流式传输。

qrs1-t4.gif

    研究发现为Mplayer添加解码器的方法有多种,总结如表1所示,本文采用了第3个方案。

qrs1-b1.gif

2 硬件模块

    S3C6410这款16/32位的微处理器,主频可达667 MHz,主处理器之外集成了MFC,如图5所示,能支持MPEG4/H.263/H.264/VC1的编解码,解码性能可达 720×480 30 f/s或者720×576 25 f/s。S3C6410还支持实时视频会议等功能。

qrs1-t5.gif

    MFC由BIT和视频编解码器组成。BIT处理器对数据流进行分解,一方面与主处理器通信来协调整个流程,另一方面控制视频解码器进行解码。BIT处理器主要包括:BIT处理器内核、程序内存、数据内存、与主处理器进行交互的接口。视频编解码器受BIT处理器的控制来完成解码,内部包含宏块控制器、预测、块效应滤波、重构等子模块。

    解码时需对中间运算缓存,图5中的外部存储器提供了这些空间,可分为BIT处理器缓冲和数据缓冲,如图6和图7。代码缓冲区的主要作用是存储启动代码。工作缓存区缓存中间结果,其配合流缓冲区进行工作。参数缓存区主要存帧缓冲的地址。主处理器对流缓冲区进行写操作,BIT处理器对其进行读操作,其缓存的是待解码的数据。帧缓冲区存储的是解码后的YUV数据。

qrs1-t6,7.gif

3 软件模块

3.1 Mplayer结构分析

    由图4知,Mplayer的结构是模块化的,各个模块在mplayer.c的协同下工作。下面对其简要分析。

    (1)stream.c所在的输入层,根据读入方式来调用文件,正如图4中stream_*.c所示,如strean_file.c、stream_ftp.c、stream_netstream.c等。这个过程通过查询、跳转、缓存等来完成。

    (2)demuxer.c所在的音视频分流层。demuxer.c是一个基本的框架,对于具体的流如mpeg-es、avi、asf等,都有相应的demux_*.c。

    (3)解码。解码器由libmpcodecs/*和分离的库组成,如liba52、libmpeg2等。Mplayer.c通过dec_audio.c 和dec_video.c 对流头sh_audio_t 和 sh_video_t中的格式进行判断来选择解码器。通过dec_audo.c来调用ad_*.c;通过dec_video.c来调用vd_*.c,即视频解码器。解码之后还需对视频后期处理,即需用到视频滤波器vf_*.c。

    (4)显示。video_out.c和audio_out.c调用不同的显示模块,如vo_directfb.c、vo_fbdev.c等。

3.2 调用MFC的API 

    应用程序调用MFC的API,现在对其进行介绍,其中涉及了Mplayer中的函数:

    SsbSipH264DecodeInit():解码实例的创建,即初始化;

    SsbSipH264DecodeGetInBuf():获取输入缓存区的地址,待解码数据从这里读取;

    以上函数作为初始化,需要在编写的vd_*.c中的初始化函数int init(sh_video_t *sh)中调用;

    SsbSipH264DecodeGetConfig():在vd_*.c的mp_image_t*

    decode(sh_video_t *sh,void* data,int len,int flags)中两处被调用:其一是为了获得视频流的信息,如分辨率的长、宽等,只能在mp_image_t* decode()第一次执行时调用,否则因时间开销而影响视频的显示,调用的格式为:SsbSipH264DecodeGetConfig(handle,H264_DEC_GETCONF_STREAMINFO, &stream_info);其二获得输出地址,格式为:SsbSipH264DecodeGetConfig(handle,H264_DEC_GETCONF_PHYADDR_FRAM_BUF,pYUVBuf)。其源码结构如下:

    static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)

    {   ……

      if(first)

      {   ……

      SsbSipMPEG4DecodeGetConfig(handle,H264_DEC_GETCONF_STREAMINFO,&strea_info);

      first=0; }

      else

    {  ……

      SsbSipMPEG4DecodeGetConfig(handle,H264_DEC_GETCONF_PHYADDR_FRAM_BUF, pYUVBuf);

      ……}

    SsbSipH264DecodeExe():在函数mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)中被调用的解码函数。

    SsbSipH264DecodeDeInit():最后对硬件资源的释放,在void uninit(sh_video_t *sh)中调用。

4 实现流程

    首先,将live555源码中live中的文件config.armlinux里的CROSS_COMPILE改为CROSS_COMPILE?=arm-linux-;然后依次执行./genMakefile armlinux、make;最后,将编译好的目录复制到/usr/local/lib 下。其次完成Mplayer软解码的移植[5]

    下面介绍如何将MFC添加到Mplayer中,这是本文的关键。

    首先,在文件etc/codecs.conf中增加解码器实体。codecs.conf是对音视频解码器的声明,其关键字是固定的,如videocodec说明是视频解码器。

    其次,编写解码器vd_mfc264.c。Mplayer定义了一个vd_functions_t型结构体。原型定义在vd.h中,如下所示:

    typedef struct vd_functions_s

    {

     vd_info_t *info;

     int (*init)(sh_video_t *sh);

     void (*uninit)(sh_video_t *sh);

     int (*control)(sh_video_t *sh,int cmd,void* arg, ...);

     mp_image_t* (*decode)(sh_video_t *sh,void* data,

    int len,int flags);

    } vd_functions_t;

    (1)int init(sh_video_t *sh)完成解码之前的初始化,包括MFC的启动以及一些API句柄的获得;

    (2)void uninit(sh_video_t *sh)是结束函数,完成解码后的资源的释放;

    (3)mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)完成解码。读取到的待解码数据填充到图7中的流缓冲区,通过与工作缓冲区的交互,将解码后的YUV数据放入图7中的帧缓冲区。

    Mplayer的视频解码器都被libmpcodec目录下vd.c中的指针数组mpcodecs_vd_drivers所管理,因此增加:

    extern  vd_functions_t  mpcodecs_vd_mfc264;

    vd_functions_t* mpcodecs_vd_drivers []=

    { ……

    #ifdef HAVE_MFC264

    &mpcodecs_vd_mfc264,

    #endif

    ……}

    (4)int control(sh_video_t *sh,int cmd,void* arg,...)的作用是控制视频的解码和显示,这个函数是为保障音视频的同步。

    再次,编写显示模块vo_mfcfb.c。S3C6410的MFC可以对解码后的数据进行缩放、滤波等后期处理。在Mplayer的源码中,是把数据传给video_out.c,然后通过调用vo_fbdev.c来使用framebuffer显示。在硬解码中,由于存储解码后的数据的物理地址,并不是在处理器的缓存中,而是在外部存储器中,这导致Mplayer的vo_fbdev.c无法获得缓存地址。解决办法就是编写vo_mfcfb.c,它完成将帧缓存区中的YUV数据进行后期处理并显示。整个流程如图4所示。将vo_mfcfb.c加入到video_out.c中,不再具体叙述。

    最后,修改Mplayer下的相关Makefile,将编写的两个源文件和相应的头文件编译成静态链接库。

5 系统测试与分析

    现在用一台PC运行live555来充当流媒体服务器,通过搭建HB,来验证手持测试仪上的流媒体播放功能。

    通过软件Media Coder将测试视频转换成编码帧率25 f/s、分辨率720×480和不同的编码码率的视频。图8从播放帧率角度显示了对比的解码性能。

qrs1-t8.gif

    分辨率为720×480、编码帧率为25 f/s的H.264视频,在Arm11平台下,要想达到人眼视觉可以接受的流畅性,Mplayer的软解只能达到的码率为500 kb/s,而使用MFC硬解可以高达3 500 kb/s,比软解码提高约3 000 kb/s。

6 结论

    流媒体最耗资源的是视频的解码,本文利用支持live555的Mplayer的成熟框架,将S3C6410的MFC添加到Mplayer的解码库中,不仅可以降低系统对CPU、内存等硬件资源的要求,而且大大提高了视频质量,这体现了嵌入式应遵循的高性价比理念。而Mplayer在嵌入式领域的应用,通常是对已有软件解码器进行算法的优化,或者直接进行移植应用[5],本文的开发方案为相关应用提供了很好的借鉴。

参考文献

[1] CONKLIN G J,GREENBAUM G S,LILLEVOLD K O,et al.Video coding for streaming media delivery on the Internet[J].IEEE Transactions on Circuits And Systems for Video Technology,2001,11(3):269-281.

[2] Samsung Electronics.S3C6410X RISC microprocessor user′s Manual[Z].2008.

[3] 国家广播电影电视总局广播科学研究院,北京大学,西安电子科技大学,上海明波通信技术股份有限公司,上海未来宽带技术及应用工程研究中心有限公司.高性能同轴电缆接入技术(HINOC)研究与实现论文集[M].辽宁:辽宁石油化工大学,2011.

[4] Mplayer.The online documentation of Mplayer[EB/OL].(2013-05-01)[2014-06-30].http://www.mplayerhq.hu/DOCS/HTML/zh_CN/intro.html.

[5] 慈文彦,何君,朱明祥.基于ARM处理器的流媒体播放器客户端的构建[J].信息技术,2012(1):106-112.

此内容为AET网站原创,未经授权禁止转载。