APP下载

基于Linphone的海思H.264硬件编码器移植

2016-09-09刘文亮夏克文

电视技术 2016年8期
关键词:海思机顶盒编码器

刘文亮,夏克文,华 中

(1.河北工业大学 信息工程学院,天津 300130;2.天津铂创国茂电子科技发展有限公司,天津 300384)



基于Linphone的海思H.264硬件编码器移植

刘文亮1,夏克文1,华中2

(1.河北工业大学 信息工程学院,天津 300130;2.天津铂创国茂电子科技发展有限公司,天津 300384)

为了缩短H.264编码时间、提高H.264编码效率,提出基于AndroidLinphone的Hi3716MV400H.264硬件编码器移植。对硬件编码器的移植方法进行详细说明,包括搭建Linphone开发环境、添加Hi3716MV400H.264硬件编码库、编写H.264硬件编码函数。经程序测试,移植了海思H.264硬件编码器的Linphone能够在Hi3716MV400机顶盒进行正常的视频通信,并且减少CPU资源占用,降低Linphone视频通话死机频率。

Hi3716MV400;H.264硬件编码器;AndroidLinphone

随着智能手机与智能机顶盒等终端设备的普及,VoIP(VoiceoverInternetProtocol)技术研发的产品得到了越来越多用户的青睐,如何使视频通话更流畅、更清晰也成为各芯片厂商和软件开发公司研究的焦点[1]。Android是2007年谷歌开发的一款基于Linux平台的开放操作系统,其开发的第三方软件完全免费,由于搭载Android系统的智能手机和平板设备占有的大量用户市场[2],因此,Android应用的开发在市场的份额越来越大,研究在Android平台上的VoIP技术具有很大应用价值[3]。Linphone就是一款基于Android开发的VoIP软件,能够进行H.264视频编解码,但是Linphone的H.264软件编码器占用较多CPU资源,存在视频画面显示卡顿、不流畅以及死机问题,本文采用华为海思Hi3716MV400机顶盒作为硬件平台,移植Hi3716MV400硬件H.264编码器到AndroidLinphone,提高了H.264编码速率,减少了处理器资源的占用,取得了较好的效果。

1 硬件系统设计

海思Hi3716芯片方案是由国产品牌海思自主研发的一种芯片方案,具体型号有三种,分别是Hi3716M、Hi3716H以及Hi3716C,本文采用的就是搭载在银河安卓高清机顶盒的Hi3716MV400芯片。该芯片采用ARM公司的CortexA9架构处理器,主频率800MHz,浮点运算速率达到1 500MI/s,集成高性能GPU,支持OpenGLES2.0/1.1/1.0OpenVG1.1,内置NEON,高速处理能力可以满足未来业务需求[4-5],集成高性能2D/3D加速引擎,可为客户提供流畅的人机交互界面和丰富游戏体验。支持MPEG2/H.264/AVS+/VP6/VP8等多种格式的高清视频解码和H.264编码,可以满足多媒体播放、转码、可视通信的要求。内置2路以太网和2路USB接口,提供灵活的连接方案。

Hi3716MV400机顶盒使用12V直流电压供电,1GbyteDDR3内存,1GbyteNANDFlash,提供10组GPIO接口,提供单个LED和KeyPAD控制接口,单个IR接收处理器,外扩单路USB口用于高清摄像头数据传入,提供RS-232调试串口用于程序的烧写、打印信息的输出与命令调试,最大支持100MbitRJ-45网口数据传输[6]。为图像输出提供高清晰度多媒体接口HDMI,模拟视频接口支持1路CVBS接口、1路YPrPb接口,输出接口可以选择配置,提供LineOut接口输出到音频设备,提供高频头。机顶盒系统硬件结构如图1所示。

图1 基于ARM的无线嵌入式Web服务器系统结构图

2 Linphone Android开发环境搭建

Linphone为开发人员提供了Android版本的源码,生成apk需要使用NDK工具,以及Androidsdk和相关的adt插件、apt安装工具。统计所需工具包如表1所示。

表1Linphone开发工具包

工具列表工具包文件安装方式NDK工具android-ndk-r9-linux-x86_64.tar.bz2解压使用AndroidLinuxSDKandroid-sdk_r21.1-linux.tgz解压使用AndroidLinux开发插件包adt-bundle-linux-x86-20130219.zip解压使用autoconfautoconf.debapt-getinstallautomakeautomake.debapt-getinstalllibtoollibtool.debapt-getinstallpkg-configpkg-config.debapt-getinstallant1.8ant1.8.debapt-getinstall

在64位Ubuntu10.04系统安装了上述源码包之后,解压Linphone源码包、进入Linphone的主目录,输入如下命令编译Linphone:

#makeBUILD_X264=1BUILD_AMRNB=0BUILD_AMRWB=0BUILD_GPLV3_ZRTP=0BUILD_SILK=0BUILD_G729=1BUILD_TUNNEL=0BUILD_WEBRTC_AECM=1USE_JAVAH=1BUILD_FOR_X86=0

“BUILD_X264=1”添加视频X264编码的支持;“BUILD_G729=1”添加对音频G729编码的支持,“BUILD_WEBRTC_AECM=1”编译回音消除,“BUILD_FOR_X86=0”不编译X86架构的liblinphone库。“BUILD_AMRNB=0”与“BUILD_AMRWB=0”表示不编译amrnb和amrwb编译码器。

编译完成后会在linphone的bin目录下生成linphone-debug.apk文件,通过adbinstall命令将apk安装到Hi3716MV400Android机顶盒,按照向导配置完账号、音视频参数即可使用Linphone。

3 Linphone分析

3.1Linphone视频数据处理

可视电话软件Linphone支持多种平台(Android,iOS,WindowsPhone8,Linux),支持H.264,VP8,MPEG-4视频软件编解码,为用户开发提供API函数。Linphone主要依赖的3个软件开发包均支持用户的二次开发:Mediastreamer2,处理音视频流的SDK,是音视频工作的引擎,具有音视频编码,声卡资源访问,视频捕获与显示,回声消除的功能。oRTP,支持RTP以及RFC3550协议的C语言开发库,为基于RTP协议传输语音和视频数据提供保障。belle-sip,是Linphone的新版belleSIP协议栈,纯C语言编写的SIP(RFC3261)实现,belle-sip提供面向对象的接口函数,是一种在UDP、TCP、TLS等网络层上层的用户代理[7]。

以Mediastreamer2为核心开发的Linphone,其各种操作都是通过MSFilter(多个MSFilter组成Graph)实现的,Mediastreamer2的总体逻辑关系非常简单,它利用函数指针将若干MSFilter组合起来,通过线程来调度这些MSFilter上的函数指针[8]。图2就是由Linphone工作时视频MSFilter之间数据传递的模块图。其中source用来获得来自摄像头的视频数据;pixconv用来处理视频格式;tee用于分流,一部分到output直接显示(当前视频预览功能),另一部分输出后通过编码与rtp发送,被另一端Linphone接收并显示。其中视频encoderMSFilter主要有H.264、MPEG4和VP8三种。

图2 MSFilter组成模块图

Linphone的video_stream_start函数详细实现了图2所示的Graph,并描述了各个MSFilter之间的关系。另外,video_stream_start函数通过检测视频流的VideoStreamRecvOnly标志,判断是否组建接受视频流数据的Graph,该Graph主要包括:decoderMSFilter,rtprecvMSFilter,displayMSFilter,pixconvMSFilter。video_stream_start是在Linphone打电话时后台调用视频流线程开始执行,同样音频流也有相应的Graph,具体实现在audio_stream_start函数,通过调用音频流线程开始数据传递。

3.2Linphone H.264 MSFilter

Linphone的H.264软件编码MSFilter源码在msx264.c文件,H.264MSFilter的编写同样符合Mediastreamer2扩展开发标准,主要由两部分构成,即编码结构体EncData和编码函数x264_enc_desc。EncData存放H.264软件编码的相关属性操作,编码函数包括enc_init,enc_preprocess,enc_process等等。EncData结构体成员参数需要使用enc_init()初始化。EncData结构体成员及其功能如表2所示。

表2EncData结构体成员

结构体成员参数功能x264_t*encx264_param_tparamsH.264编码器句柄H.264编码器的属性参数vsize;bitrate;fps;mode;Rfc3984Contex*packer;keyframe_intVideoStarterstartergenerate_keyframe分辨率,比特率,帧率,编码模式rfc3984协议包容器关键帧数目关键帧时间记录关键帧标志

初始化完成后运行H.264的软件编码预处理函数enc_preprocess()和处理函数enc_process(),两者分别完成如下功能:

enc_preprocess(),H.264编码的预处理函数,新建一个rfc3984容器包,rfc3984_set_mode()设置当前包的模式为0,rfc3984_enable_stap_a()设置当前包为非单时间聚合包。创建x264_param_t指针变量params,初始化该编码参数,调用apply_bitrate()并将params各参数应用到H.264编码器,使用x264_encoder_open()打开该编码器。

enc_process(),通过while循环,利用ms_queue_get()不断从MSFilter的input缓冲队列中获取视频的帧图像数据,执行ms_yuv_buf_init_from_mblk()将接受的数据转换成yuv格式,再将yuv格式数据转化为x264_picture_t,准备在发送初始帧数据2s或者4s之后发送I帧,x264_encoder_encode()将输入的x264_picture_t型数据转码成x264_nal_t型编码数据,x264_nals_to_msgb()将视频数据依次放入到mblk_t类型变量的队列中,使用rfc3984_pack()对编码后的数据进行RTP打包传给rtpsendMSFilter。

4 H.264硬件编码器移植

4.1sample_venc程序的改进

Hi3716MV400的H.264硬件编码模块为VENC(VideoEncoder),VENC模块对接收前端模块或客户发送的视频、图形数据,通过做帧率控制、码率控制、帧间预测、帧内预测、变换、量化等协议/算法处理,按照客户需求的输出帧率、目标码率、分辨率等生成码流返回给客户使用。

VENC视频数据推送支持绑定模式和外部用户送帧模式,其中绑定模式需要前级模块(VI)自动将待编码数据送入VENC,而外部用户送帧模式需要用户态线程一直给VENC送帧编码,用户需要自行循环调用HI_UNF_VENC_QueueFrame()和HI_UNF_VENC_DequeueFrame()来给编码器送帧并回收编码完成的帧数据,保存或者网络传输。

VENC例程sample_venc采用用户送帧模式读取yuv文件,进行H.264硬件转码之后保存成.h264文件。但在可视电话实时H.264编码中,需要不断地从已经分配好的内存空间读取yuv数据,进行H.264硬件转码之后将转码后的数据保存在一段分配了空间的内存区域以便其他函数对编码后的数据进行处理,于是修改sample_venc.c的源程序,编写函数HI_S32venc(HI_U8*yuv,nal_s*nal)。程序流程图如图3所示。

执行函数HI_SYS_Init()对模块进行初始化,通过HI_UNF_VENC_GetDefaultAttr()获取编码通道默认属性stVeAttr,设置stVeAttr的各个成员变量,包括编码协议类型、编码输出宽度和高度、输入帧率、目标码率和目标帧率、图像组长度,根据HI_ADP_VENC_Create

图3venc程序流程图

(stVeAttr)创建VENC通道,执行HI_ADP_VENC_Start()开始硬件转码,新建线程SampleSendFrameRoutine读取数据并进行硬件转码,新建线程SampleVencRoutine获取硬件编码后的数据。最后等待两个线程的结束与执行系统去初始化操作。

线程SampleVencRoutine的说明:使用HI_UNF_VENC_AcquireStream()获取视频编码码流,将码流数据保存在pArgs→out_nal→nal_data开始的pArgs→out_nal→nals_size长空间中,然后使用HI_UNF_VENC_ReleaseStream()释放视频编码码流。

线程SampleSendFrameRoutine的说明:为变量u32TmpData分配空间用于保存输入硬件编码器的数据,通过stFrameinfo设置帧信息属性参数,将u32TmpData与stFrameinfo的stVideoFrameAddr成员关联,将输入的视频帧数据从YUV422格式转换为YUV420格式,通过HI_UNF_VENC_QueueFrame()向编码器送帧,HI_UNF_VENC_DequeueFrame()向编码器索取还帧,完成整个H.264硬件编码的流程。

海思H.264硬件编码函数为HI_S32venc(HI_U8*yuv,nal_s*nal),输入参数为HI_U8*yuv,输出参数为HI_U8*nal,函数返回值类型为HI_S32,其中yuv为YUV420P数据,分别保存在AVFrame类型变量的data[0]、data[1]和data[2]中,nal_s结构体声明如下:

typedefstruct_nal_s{

HI_U8*nal_data;//naldata

HI_S32nal_num;//everynalnum

HI_S32nals_size;//nalstotal

}nal_s;

其中,nal_data为进行H.264硬件编码后存储数据的首地址,nal_num为nals的个数,nals_size为H.264硬件编码后数据总量。

4.2硬件编码模块venc使用

Linphone的H.264软件编码函数为msx264.c文件的x264_encoder_encode(),因此可以直接将其替换为函数venc()。在enc_process()中利用avcodec_get_frame_defaults()获取帧数据到pict(AVFrame类型),通过avpicture_fill()填充数据,将x264_encoder_encode()替换为硬件编码函数venc(),修改x264_nals_to_msgb()函数,计算转码后的H.264数据nals个数,跳过nals头起始码“00 00 00 01”或者“00 00 01”,将有效的帧数据通过ms_queue_put()放到MSFilter的队列中,之后依次通过SETBITRATEMSFilter和ADDFMTPMSFilter进行数据传递。

x264_nals_to_msgb未修改之前的格式如下:

staticvoidx264_nals_to_msgb(x264_nal_t*xnals,intnum_nals,MSQueue*nalus)

xnals用于存储H.264编码后的数据,num_nals表示nals的个数,nalus用于MSQueue队列传递数据。

修改之后的x264_nals_to_msgb函数如下:

staticvoidx264_nals_to_msgb(nal_s*xnals,MSQueue*nalus)

xnals同样用于存储H.264编码后的数据,同时存储nals的个数和数据总量,nalus用于MSQueue队别传递数据。但是函数的具体实现发生改变。由于在实际的H.264数据帧中往往帧前带有00 00 00 01分隔符,所以程序首先检测00 00 00 01标志字,移动m→b_wptr指针跳过四位标志字,直接指向H.264帧数据,最后通过ms_queue_put将数据放到nalus。实际上修改后的x264_nals_to_msgb()函数将能够自动计算nals的个数。

4.3Linphone添加venc模块支持

若使Linphone能够支持Hi3716MV400SDK的开发例程sample_venc以及改进的编码函数venc,需要将sample_venc依赖的头文件和库文件分别拷贝到NDK的include和lib文件夹,修改Linphone各个模块编译的Android.mk文件,利用NDK重新编译并生成apk。修改的内容分为以下3个步骤:

1)修改submoduleslinphoneuildandroid目录下的Android-no-neon.mk、Android.mk以及Common.mk,修改submoduleslinphonemediastreamer2uildandroid目录下的Android.mk,分别在上述4个文件中添加对海思库的支持,通过标志字LOCAL_LDLIBS指定附加的系统库文件,添加的内容如下:

LOCAL_LDLIBS+=-llog-ldl-lcutils-lhi_common-lhi_msp-lhi_sample_common

2)在AndroidLinphone源码的根目录执行第2节编译命令,生成apk。需要注意的是每次修改c源码均需要输入编译命令重新生成apk进行安装与调试。

5 测试与结果

本测试系统由SIP服务器miniSipServer和2个Linphone可视电话终端组成(Windows版Linphone和移植H.264硬件编码器Android版Linphone)。miniSipServer是一款采用标准SIP协议的软件,能接入各种采用SIP协议的软终端,为搭建局域网可视电话通信系统,以miniSipServer作为主SIP软件,2个Linphone分别经过miniSipServer的SIP控制进行RTP流的传输。

局域网内视频通话的各项参数测试结果:视频通话采用H.264图像编码格式,码率300kbit/s左右,帧速率17f/s(帧/秒),上传图像速度400kbit/s,下载速度100kbit/s,图像分辨率CIF(352×288),本地显示分辨率为(352×288),语音编码格式为GSM,编码速率25kbit/s左右。测试结果表明视频传输与视频显示各项参数达到了预期的效果。2个可视电话客户端在局域网内的视频截图如图4和图5所示。

图4 机顶盒Linphone视频画面(截图)

图5 Windows版Linphone视频画面(截图)

测试Linphone视频通话方式分为局域网内通话和互联网远程通话,局域网内直接运行miniSipServer充当SIP服务器进行音视频数据传输(需要在miniSipServer建立2个SIP账号,两个客户端分别用账号登录),互联网则采用Linphone内部的SIP服务器进行通信(需要2个客户端分别在Linphone官网注册linphone.orgSIP账号,客户端登录)。测试结果表明,移植了H.264硬件编码的机顶盒在局域网或者互联网下占用的CPU资源均较少,且使用率波动较小,比较稳定。表3是对移植H.264硬件编码器的机顶盒画面情况、CPU资源占用、死机次数的统计情况。

表3不同网络条件下参数对比

网络环境画面情况CPU资源使用率/%视频通话中死机频率局域网、H.264软件编码局域网、H.264硬件编码清晰、流畅清晰、流畅5.84.7~5.03/501/50互联网、H.264软件编码互联网、H.264硬件编码清晰、有卡顿清晰、有卡顿6.0~9.05.6~7.76/501/50

6 结束语

本文介绍了基于Hi3716MV400的高清多媒体处理芯片,在Ubuntu10.04搭建AndroidLinphone开发环境,实现Hi3716MV400H.264硬件编码函数venc在AndroidLinphone的移植,移植完成后对Linphone进行视频通信实验。实验结果表明,移植了H.264硬件编码器的Linphone系统能够实时、清晰地进行视频通话并显示,而且相比软件H.264软件编码占用CPU资源更少,更稳定。但是在视频画面传输速率、视频分辨率的设置方面仍然有待提高,视频画面有卡顿的问题也需要解决。

[1]贺丹丹,施展.基于Android的VoIP系统的设计与实现[J].现代电子技术,2011,34(6):28-31.

[2]邵长彬,张重阳,郑世宝.基于Android的可视IP电话多媒体终端设计与实现[J].电视技术,2011, 35(6):62-65.

[3]杨瑞.基于协议栈数字机顶盒VoIP终端的设计与实现[J].电视技术,2011,35(23):71-74.

[4]张宝柱,范自来.基于海思Hi3716C平台的安卓DVB—T2机顶盒设计方案研究[J].有线电视技术, 2014,1(2): 46-48.

[5]赵宇峰.基于嵌入式Linux的实时视频通信的实现[J].电视技术,2012,36(19):189-192.

[6]王东东.基于Hi3716C的Android机顶盒软件设计与实现[D].天津:天津大学,2012.

[7]赵明.基于SIP的军事车载VOIP语音终端软件的设计与实现[J].火力与指挥控制,2014,39(z1): 113-115.

[8]沙爱军,沈卫康,毛其林.基于LINPHONE的嵌入式VoIP终端实现[J].信息通信,2013(8):77-79.

刘文亮(1990— ),硕士生,主研智能信息处理;

夏克文(1965— ),博士生导师,主要研究方向为智能信息处理,压缩感知,半定规划,支持向量机;

华中(1970— ),博士,主要研究方向为微电子与固体电子学。

责任编辑:闫雯雯

HisiliconH.264hardwareencodertransplantationbasedonLinphone

LIUWenliang,XIAKewen,HUAZhong

(1.School of Information Engineering, Hebei University of Technology, Tianjin 300130,China;2.Tianjin Botro Electronical Science and Tech. Co., Ltd., Tianjin 300384,China)

InordertoshortenH.264encodingtimeandimproveencodingefficiency,anideaabouttranslatingHi3716MV400H.264hardwareencodertoAndroidLinphonecomeup.Inthispaper,thetransplantationmethodofthehardwareencoderisdescribedindetailwhichincludesbuildingLinphonedevelopmentenvironment,addingH.264hardwareencodinglibrary,correctingH.264hardwareencodingfunction.ExperimentaltestsshowthattheLinphonecancommunicatewithanotherclientnormallyinHi3716MV400STB,makingthevideocommunicationoccupieslessCPUresourcesandcrashesrarely.

Hi3716MV400;H.264hardwareencoder;AndroidLinphone

TN915;TP393

ADOI:10.16280/j.videoe.2016.08.025

河北省引进留学人员基金项目(C2012003038)

2015-10-19

文献引用格式:刘文亮,夏克文,华中. 基于Linphone的海思H.264硬件编码器移植[J].电视技术,2016,40(8):126-131.

LIUWL,XIAKW,HUAZ.HisiliconH.264hardwareencodertransplantationbasedonLinphone[J].Videoengineering,2016,40(8):126-131.

猜你喜欢

海思机顶盒编码器
融合CNN和Transformer编码器的变声语音鉴别与还原
华为海思宣布推出首款华为海思LTE Cat4平台Balong 711
机顶盒上别盖布
安全使用机顶盒注意五点
解密华为芯片技术实力
何庭波:逼出来的华为“芯片女皇”
基于双增量码道的绝对式编码器设计
应用旋转磁场编码器实现角度测量
有线电视高清数字电视机顶盒测试系统的构建
基于数字信号处理的脉冲编码器