文獻標識碼: A
文章編號: 0258-7998(2014)10-0009-03
0 引言
多媒體的呈現方式從本地播放、下載存儲播放逐步發(fā)展到流式播放[1]。流媒體融合了網絡和多媒體編解碼等技術,雖然在PC 領域上的應用已比較成熟,但是在嵌入式領域,仍有著很大的開發(fā)空間。文中提到的向Mplayer的解碼庫中添加S3C6410的多媒體編解碼模塊MFC(multi format codec)[2],具有很強的應用價值。
本設計的平臺是HINOC手持測試儀。HINOC[3](High performance Network Over Coax)是“三網融合”中的從光纖網到用戶的一個傳輸方案,如圖1所示。頭端設備(HINOC Brige,HB)對多個終端設備(HINOC Modem,HM)進行管理。
HINOC 手持測試儀的主要功能是不僅有 HM的功能,還能協(xié)助工程人員進行故障定位。圖2和圖3顯示了其硬件和軟件結構。
工作人員通過流式傳輸可以觀看遠程業(yè)務視頻,而且能直觀地驗證網絡的底層是否連通。
1 需求分析
本系統(tǒng)采用了ARM-Linux,處理器是基于ARM1176JZF-S的S3C6410,播放器是Linux系統(tǒng)上最優(yōu)秀的播放器之一Mplayer[4],結構如圖4所示。將S3C6410的MFC加入Mplayer的解碼庫中,通過移植協(xié)議棧live555,Mplayer支持流式傳輸。
研究發(fā)現為Mplayer添加解碼器的方法有多種,總結如表1所示,本文采用了第3個方案。
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還支持實時視頻會議等功能。
MFC由BIT和視頻編解碼器組成。BIT處理器對數據流進行分解,一方面與主處理器通信來協(xié)調整個流程,另一方面控制視頻解碼器進行解碼。BIT處理器主要包括:BIT處理器內核、程序內存、數據內存、與主處理器進行交互的接口。視頻編解碼器受BIT處理器的控制來完成解碼,內部包含宏塊控制器、預測、塊效應濾波、重構等子模塊。
解碼時需對中間運算緩存,圖5中的外部存儲器提供了這些空間,可分為BIT處理器緩沖和數據緩沖,如圖6和圖7。代碼緩沖區(qū)的主要作用是存儲啟動代碼。工作緩存區(qū)緩存中間結果,其配合流緩沖區(qū)進行工作。參數緩存區(qū)主要存幀緩沖的地址。主處理器對流緩沖區(qū)進行寫操作,BIT處理器對其進行讀操作,其緩存的是待解碼的數據。幀緩沖區(qū)存儲的是解碼后的YUV數據。
3 軟件模塊
3.1 Mplayer結構分析
由圖4知,Mplayer的結構是模塊化的,各個模塊在mplayer.c的協(xié)同下工作。下面對其簡要分析。
(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():解碼實例的創(chuàng)建,即初始化;
SsbSipH264DecodeGetInBuf():獲取輸入緩存區(qū)的地址,待解碼數據從這里讀?。?/p>
以上函數作為初始化,需要在編寫的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()第一次執(zhí)行時調用,否則因時間開銷而影響視頻的顯示,調用的格式為: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源碼中l(wèi)ive中的文件config.armlinux里的CROSS_COMPILE改為CROSS_COMPILE?=arm-linux-;然后依次執(zhí)行./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中的流緩沖區(qū),通過與工作緩沖區(qū)的交互,將解碼后的YUV數據放入圖7中的幀緩沖區(qū)。
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,它完成將幀緩存區(qū)中的YUV數據進行后期處理并顯示。整個流程如圖4所示。將vo_mfcfb.c加入到video_out.c中,不再具體敘述。
最后,修改Mplayer下的相關Makefile,將編寫的兩個源文件和相應的頭文件編譯成靜態(tài)鏈接庫。
5 系統(tǒng)測試與分析
現在用一臺PC運行l(wèi)ive555來充當流媒體服務器,通過搭建HB,來驗證手持測試儀上的流媒體播放功能。
通過軟件Media Coder將測試視頻轉換成編碼幀率25 f/s、分辨率720×480和不同的編碼碼率的視頻。圖8從播放幀率角度顯示了對比的解碼性能。
分辨率為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的解碼庫中,不僅可以降低系統(tǒng)對CPU、內存等硬件資源的要求,而且大大提高了視頻質量,這體現了嵌入式應遵循的高性價比理念。而Mplayer在嵌入式領域的應用,通常是對已有軟件解碼器進行算法的優(yōu)化,或者直接進行移植應用[5],本文的開發(fā)方案為相關應用提供了很好的借鑒。
參考文獻
[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.