摘 要: 提出了一種視頻在i.MX51平臺(tái)的硬件解碼方案,詳細(xì)描述了使用VPU進(jìn)行視頻硬件解碼的邏輯處理過(guò)程及解碼流程,。使用本方案將MPEG4格式的視頻文件在Android平臺(tái)進(jìn)行解碼并獲得成功,。對(duì)于使用i.MX51進(jìn)行多媒體開(kāi)發(fā)具有重要的指導(dǎo)意義。
關(guān)鍵詞: i.MX51開(kāi)發(fā)板,; 硬件解碼,; VPU; MPEG4
隨著多媒體技術(shù)的迅速發(fā)展,,數(shù)字視頻的應(yīng)用越來(lái)越廣泛,。人們對(duì)高清視頻的狂熱追逐給視頻解碼帶來(lái)了巨大的壓力[1]。傳統(tǒng)的軟件解碼方法已經(jīng)很難滿足視覺(jué)要求,。高清視頻的分辨率遠(yuǎn)遠(yuǎn)高于一般格式視頻,,其碼率也很高,再加上視頻編碼標(biāo)準(zhǔn)的壓縮率高,使得解碼運(yùn)算量很大,。因此,常規(guī)地直接用CPU解碼會(huì)極大地消耗CPU的運(yùn)算能力,,于是轉(zhuǎn)向硬件解碼。硬件解碼是通過(guò)顯卡的視頻加速功能對(duì)高清視頻進(jìn)行解碼,能夠?qū)PU從繁重的視頻解碼運(yùn)算中釋放出來(lái),,使計(jì)算機(jī)具備流暢播放高清視頻的能力,。本文通過(guò)研究主流Android開(kāi)發(fā)板i.MX51上的VPU,給出了使用VPU實(shí)現(xiàn)視頻硬件解碼的主要流程和方法,。
1 i.MX51 EVK平臺(tái)硬件視頻解碼方案
1.1 i.MX51處理器的特性
i.MX51 是飛思卡爾公司自主研發(fā)的ARM體系結(jié)構(gòu)的中央處理器單元,。i.MX51處理器采用了先進(jìn),、高效率的ARM Cortex A8 內(nèi)核,處理器運(yùn)行在800 MHz的高速下[2],。相比于ARM11產(chǎn)品,,其性能被大大提高。它支持最高200 MHz的DDR2和移動(dòng)DDR DRAM時(shí)鐘速率,,擁有32 KB的指令緩存和數(shù)據(jù)緩存以及256 KB的二級(jí)緩存[3],;處理器內(nèi)部集成了DDR/DDR2內(nèi)存控制器;同時(shí)集成了矢量運(yùn)算,、浮點(diǎn)運(yùn)算以及ARM NEON SIMD媒體和信號(hào)處理器,,為多媒體信息娛樂(lè)終端提供了強(qiáng)大的處理核心支持。
1.2 i.MX51 VPU
i.MX51 VPU(視頻處理單元)是一個(gè)支持多標(biāo)準(zhǔn)編解碼操作的高性能的視頻編解器引擎,。VPU編解碼器支持MPEG-1/2,、MJPEG、H.264,、MPEG-4的編解碼,。 VPU在i.MX51上支持的解碼高達(dá)HD水平,編碼為SD水平,。VPU通過(guò)32 bit的APB總線和64 bit的AXI總線與系統(tǒng)聯(lián)絡(luò),,APB總線用于系統(tǒng)控制,AXI總線用于數(shù)據(jù)的傳輸,。同進(jìn),,利用片上存儲(chǔ)器實(shí)現(xiàn)高性能。
VPU中的視頻硬件模塊被最佳化設(shè)計(jì)以用來(lái)在不同的視頻標(biāo)準(zhǔn)中共享使用,,并提供強(qiáng)大的性能和超低的功耗,,如圖1所示。
VPU提供一套主控接口寄存器,,通過(guò)這些寄存器主處理器可以簡(jiǎn)單,、高效地控制VPU。VPU擁有一個(gè)16 bit的DSP內(nèi)核——位處理器,,通過(guò)該位處理器可以控制內(nèi)部硬件模塊并實(shí)現(xiàn)視頻編解碼操作,。
1.3 視頻解碼方案
i.MX51開(kāi)發(fā)板具有支持多種操作系統(tǒng)的特性,例如Android等實(shí)時(shí)OS,。為了能夠獲得較好的推廣應(yīng)用,,采用比較流行的Android系統(tǒng)。
在Android中創(chuàng)建自己的解碼函數(shù)庫(kù),,通過(guò)JNI穿越系統(tǒng)的應(yīng)用框架層直接訪問(wèn)庫(kù)函數(shù),才能實(shí)現(xiàn)Android系統(tǒng)下對(duì)硬件的直接調(diào)用和控制,。首先,使用C語(yǔ)言對(duì)VPU的API組織調(diào)用,實(shí)現(xiàn)視頻的解碼,;然后,,生成相應(yīng)的動(dòng)態(tài)庫(kù),,并提供給JNI相應(yīng)的應(yīng)用接口,;最后,在Java類中使用C實(shí)現(xiàn)視頻解碼的本地方法,。
2 VPU解碼的內(nèi)部邏輯
2.1 VPU的初始化
VPU中位處理器用于處理比特流數(shù)據(jù),,位處理器是一個(gè)高度優(yōu)化的,它還可控制VPU與主處理器之間的通信[4],。位處理器固件被分為兩部分來(lái)進(jìn)行視頻的解碼:一部分是引導(dǎo)代碼,,這些代碼是主處理器通過(guò)IP總線下載到位處理器內(nèi)部存儲(chǔ)器的,啟動(dòng)代碼大小為1 KB,,這些啟動(dòng)代碼被寫(xiě)在外部存儲(chǔ)器一塊區(qū)域中,,固件區(qū)域的基地址由VPU的API寫(xiě)入;另一部分是進(jìn)行解碼處理的固件包,,在開(kāi)始解碼前,,固件先被寫(xiě)進(jìn)外部存儲(chǔ)器啟動(dòng)代碼之后的一塊連續(xù)的區(qū)域中,運(yùn)行過(guò)程中,,位處理器自行下載固件,,根據(jù)不同的解碼標(biāo)準(zhǔn)下載到相應(yīng)的內(nèi)部存儲(chǔ)器中,它是通過(guò)AXI總線進(jìn)行加載的,,VPU初始化過(guò)程如圖2所示,。
2.2 VPU與應(yīng)用程序的交互
圖3給出了位處理器和VPU視頻處理核心模塊,并且指明了VPU如何與應(yīng)用軟體進(jìn)行交互,。從根本上說(shuō),,在框架水準(zhǔn)之上,主處理器是通過(guò)API與主處理器進(jìn)行通信的,。
2.3 VPU的硬件抽象層
圖4為VPU的硬件抽象層的詳細(xì)內(nèi)容,。VPU的解碼器的寄存器頭文件vpu_reg.h中定義了內(nèi)存映射地址;頭文件vpu_io.h中定義了I/O操作的各種定義,,聲明了I/O操作的各種函數(shù),并在vpu_io.c中實(shí)現(xiàn)了其頭文件中的各個(gè)函數(shù),;vpu_lib.c是VPU的庫(kù)函數(shù),實(shí)現(xiàn)了VPU編解碼的所有操作,;vpu_lib.h中定義了VPU函數(shù)庫(kù)中的數(shù)據(jù)類型,、數(shù)據(jù)結(jié)構(gòu),并聲明了各個(gè)函數(shù),;vpu_util.c中是與VPU中位處理器相關(guān)的各種操作,。
3 VPU硬件解碼流程分析
3.1 VPU進(jìn)行視頻解碼的流程
通過(guò)VPU解碼的基本流程包括以下步驟:
(1)調(diào)用函數(shù)Init()來(lái)初始化VPU;
(2)使用函數(shù)DecOpen()打開(kāi)一個(gè)解碼器實(shí)例;
(3)為了能夠提供合適數(shù)量的字節(jié)流,,使用DecGetBitstreamBuffer()獲取字節(jié)流緩沖地址,;
(4)在改變解碼器的輸入流之后,使用DecUpdateBit-
streamBuffer()通知傳輸?shù)阶止?jié)流緩沖區(qū)的字節(jié)數(shù)量;
(5)在進(jìn)行一個(gè)圖片的解碼操作之前,,使用DecGetInitialInfo()來(lái)為解碼操作獲取重要的參數(shù),,如圖片大小、幀緩沖等,;
(6)使用返回的幀緩沖大小配置幀緩沖區(qū)合適的大小,,并且使用函數(shù)DecRegisterFrameBuffer()把這個(gè)數(shù)據(jù)傳達(dá)給i.MX51 VPU。
(7)使用DecStartOneFrame()開(kāi)始圖片解碼器操作,,一張一張地進(jìn)行圖片解碼,;
(8)等待完成圖片解碼器操作的中斷事件;
(9)使用DecGetOutputInfo()檢查解碼器操作的結(jié)果,;
(10)播放第n幀后,,使用DecClrDispFlag()清除播放緩沖標(biāo)志;
(11)如果還有更多的比特需要解碼,,返回到步驟(7)繼續(xù)執(zhí)行,,否則就執(zhí)行下一步;
(12)使用DecClose()關(guān)閉實(shí)例,,終止操作,;
(13)調(diào)用UnInit()釋放系統(tǒng)資源。
3.2 數(shù)據(jù)處理與控制
VPU擁有一個(gè)專用的路徑進(jìn)行主處理器與VPU之間的數(shù)據(jù)或信息的交流,,即共享存儲(chǔ)器,。共享存儲(chǔ)器通過(guò)ABMA主總線被訪問(wèn),使用這個(gè)存儲(chǔ)器進(jìn)行比特流和數(shù)據(jù)幀的交換,。通過(guò)使用VPU寄存器中的主控寄存器來(lái)實(shí)現(xiàn)主處理器與VPU之間專一的信息交流路徑,。所有在主處理器與VPU之間的命令和響應(yīng)都是通過(guò)這些寄存器來(lái)交換的。數(shù)據(jù)轉(zhuǎn)換與命令及響應(yīng)相關(guān)的信息也是通過(guò)主控寄存器來(lái)交換的,。從主處理器可以訪問(wèn)VPU主控接口的所有寄存器,。一些主控寄存器用于交換實(shí)際的命令和響應(yīng),另一些寄存器則用來(lái)向主處理器提供VPU內(nèi)部狀態(tài)信息,。
主應(yīng)用程序通過(guò)API發(fā)送命令和相應(yīng)的參數(shù)給VPU來(lái)控制VPU,。從VPU接收到一個(gè)中斷之后,發(fā)送要求的操作已經(jīng)完成的信息,。如圖5所示為應(yīng)用程序數(shù)據(jù)處理的過(guò)程,。
每個(gè)API的定義包括請(qǐng)求命令和輸入輸出數(shù)據(jù)結(jié)構(gòu)。從API給出的命令經(jīng)常被寫(xiě)進(jìn)一個(gè)專用的I/O寄存器,,但是輸入和輸出數(shù)據(jù)結(jié)構(gòu)是通過(guò)一套包括輸入?yún)?shù)和輸出結(jié)果的I/O命令寄存器傳輸?shù)摹?br />
所有的像素?cái)?shù)據(jù)或者數(shù)據(jù)流處理被主處理器執(zhí)行或者通過(guò)在SDRAM中的共享內(nèi)存被VPU執(zhí)行,。為了保證主處理器與VPU之間的安全性,,所需信息被存放在主控寄存器中。這些事務(wù)一般都是單向的,,VPU或主處理器寫(xiě)數(shù)據(jù),,其他設(shè)備在一個(gè)單數(shù)據(jù)緩沖區(qū)讀取數(shù)據(jù)。
4 視頻硬件解碼在Android下的應(yīng)用
4.1 MPEG-4在i.MX51上的硬件解碼實(shí)現(xiàn)
本文以MPEG-4視頻流為例實(shí)現(xiàn)其硬件解碼,。圖6為MPEG4的解碼流程,。
(1)初始化VPU
用BIT Code Download命令下載BITProcessor固件到存儲(chǔ)器;設(shè)置初始化參數(shù)用于對(duì)BIT Processor進(jìn)行一般性設(shè)置,,設(shè)置工作緩沖區(qū)基址,、BIT Code存儲(chǔ)器地址、比特流緩沖區(qū)控制等,;命令BIT Run Start運(yùn)行BIT處理器初始化VPU。
(2)創(chuàng)建并初始化一個(gè)MPEG-4解碼進(jìn)程
設(shè)置SEQ_INIT參數(shù),,這一過(guò)程通過(guò)調(diào)用MPEG4_initial()進(jìn)行解碼初始化,,包括打開(kāi)文件、設(shè)置硬件參數(shù)(如codec),、解碼參數(shù)初始化(如波特率設(shè)置),、申請(qǐng)地址空間(如配置基地址);運(yùn)行SEQ_INIT命令,,開(kāi)始一個(gè)MPEG-4解碼進(jìn)程,。如果出現(xiàn)Wait BusyFlag=0,則等待BIT處理器完成SEQ_INIT命令的執(zhí)行,以進(jìn)行接下來(lái)的處理,。
(3)運(yùn)行MPEG-4解碼進(jìn)程
設(shè)置PICTURE_RUN參數(shù)配置幀源地址和目標(biāo)地址,;運(yùn)行PICTURE_RUN命令,通過(guò)調(diào)用MPEG4_continue()啟動(dòng)MPEG-4的解碼進(jìn)程,。以幀為單位完成讀輸入,、解碼和寫(xiě)輸出的工作。返回1代表解碼正常,,可對(duì)其本身進(jìn)行再調(diào)用,,實(shí)現(xiàn)下一幀的解碼;返回0則代表文件結(jié)束或者出現(xiàn)異常,。如果出現(xiàn)Wait BusyFlag=0,則等待BIT處理器完成PICTURE_RUN命令的執(zhí)行,。它也意味著結(jié)束了一幀數(shù)據(jù)的解碼,將解碼后的數(shù)據(jù)發(fā)送到圖像處理單元進(jìn)行后處理并播放,。
(4)繼續(xù)執(zhí)行第(3)步,,如果比特流緩沖區(qū)是空的,則在運(yùn)行下一幀解碼之前,,主處理器應(yīng)該下載新的比特流到比特流緩沖區(qū),。
(5)運(yùn)行SEQ_END命令調(diào)用MPEG4_stop(),,編碼完成終止解碼進(jìn)程。對(duì)硬件進(jìn)行設(shè)置,,并釋放內(nèi)存空間,。
一般而言,不同編碼標(biāo)準(zhǔn)的解碼處理流程是相似的,,盡管不同的編碼標(biāo)準(zhǔn)對(duì)應(yīng)的固件版本有小幅改進(jìn),,但其具體的執(zhí)行過(guò)程是由VPU驅(qū)動(dòng)來(lái)完成的。
4.2 Android平臺(tái)使用VPU硬件解碼
之前的解碼是用C語(yǔ)言編譯通過(guò)的,而開(kāi)發(fā)板i.MX51上運(yùn)行的是Android系統(tǒng),,需要在Android系統(tǒng)上對(duì)解碼實(shí)現(xiàn),,本文采用的是JNI技術(shù)。
首先,編寫(xiě)Mikefile文件并編譯,;接著,在終端中進(jìn)入工程目錄,,運(yùn)行ndk-build命令進(jìn)行編譯,編譯通過(guò)后即可生成動(dòng)態(tài)庫(kù)文件libvpu.so,;最后,在Java文件代碼中對(duì)本地庫(kù)進(jìn)行調(diào)用,。使用public native String stringFromJNI()申明本地方法;使用System.loadLibrary()來(lái)加C動(dòng)態(tài)庫(kù),。至此,,對(duì)本地庫(kù)的調(diào)用即完成。
本文深入地分析和研究了i.MX51開(kāi)發(fā)板的功能特性,,詳細(xì)介紹了其硬件解碼模塊的內(nèi)部結(jié)構(gòu)和使用方法,,并具體說(shuō)明了其應(yīng)用程序接口函數(shù)。在此基礎(chǔ)之上,,探討了其一般使用流程,,并用MPEG4的具體解碼過(guò)程進(jìn)行了說(shuō)明,最后在Android系統(tǒng)下實(shí)現(xiàn),。實(shí)驗(yàn)結(jié)果表明其運(yùn)行情況良好,。
參考文獻(xiàn)
[1] 李強(qiáng)申.Linux視頻硬件解碼技術(shù)與應(yīng)用研究[D].北京:北京郵電大學(xué), 2009.
[2] 王知航.基于i.MX51芯片和Android平臺(tái)平板電腦電源管理的研究與應(yīng)用[D].西安:西安電子科技大學(xué),2011.
[3] i.MX51:應(yīng)用處理器開(kāi)發(fā)評(píng)估方案[J].世界電子元器件,2010(3):22-23.
[4] Freescale公司. i.MX51多媒體應(yīng)用處理器參考手冊(cè)[S].2010.