0 引言
隨著多媒體技術(shù)及寬帶網(wǎng)絡(luò)傳輸技術(shù)的發(fā)展,視頻采集及傳輸系統(tǒng)作為遠(yuǎn)程視頻監(jiān)控、可視電話會(huì)議和工業(yè)自動(dòng)控制領(lǐng)域的一項(xiàng)核心關(guān)鍵技術(shù),近年來(lái)也得到了飛速的發(fā)展。本文所提出的系統(tǒng)是在新一代基于ARM926EJ-S微處理核的嵌入式開發(fā)平臺(tái)上進(jìn)行的,并將國(guó)際上流行的MPEG-4壓縮編解碼技術(shù)和流媒體傳輸技術(shù)相結(jié)合。該系統(tǒng)具有較強(qiáng)的實(shí)時(shí)性、可交互性及便攜性。
1 系統(tǒng)開發(fā)硬件平臺(tái)
本設(shè)計(jì)采用的開發(fā)平臺(tái)是Freescale i.MX家族的MC9328MX21,作為整個(gè)系統(tǒng)的核心微處理器,其ARM926EJ-S核提供了加速的Java支持和高度整合的系統(tǒng)功能模塊,如片上模塊包括圖像加速模塊、LCD控制器、USB控制模塊、CMOS傳感器接口及同步串口等,為開發(fā)者進(jìn)行多媒體應(yīng)用開發(fā)提供了豐富的外圍接口。核心板上集成了64MB SDRAM以及16MBFlash存儲(chǔ)器,底板資源包括4個(gè)四線RS-232串口、1個(gè)10 Mbit·s-1/100 Mbit·s-1自適應(yīng)以太網(wǎng)接口及音視頻采集設(shè)備,為系統(tǒng)設(shè)計(jì)時(shí)的交叉編譯及多媒體數(shù)據(jù)的處理提供了方便。
系統(tǒng)的關(guān)鍵外圍設(shè)備、視頻數(shù)據(jù)的采集所使用的CMOS圖像傳感器OV9640,與傳統(tǒng)的CCD圖像傳感器相比,具有功耗低、體積小、集成度高等優(yōu)點(diǎn),并且OV9640支持VGA、QVGA、CIF等多種解析度,支持的數(shù)據(jù)格式包括YCrCb 4:2:2、GRB 4:2:2和RGB:RawData這3種,圖像幀傳輸速率達(dá)30幀/s。傳感器通過(guò)CSI模塊進(jìn)行圖像數(shù)據(jù)的采集,然后通過(guò)專用總線傳輸至PRP(eMMA Pre-processor),在PRP中調(diào)整圖像大小并轉(zhuǎn)換成合適的顏色空間。PRP的輸出分成2個(gè)通道,通道1輸出RGB565格式數(shù)據(jù)作為L(zhǎng)CD的顯示,通道2輸出YUV420格式數(shù)據(jù)進(jìn)行MPEG或者JPEG編碼。圖1是圖像傳感器和MC9328MX21的連接原理圖。
在兩者連接中,各模塊端口的作用分別是:CSI端口為傳輸圖像數(shù)據(jù);I2C端口為配置傳感器;GPIO為控制傳感器。
MC9328MX21的CSI模塊有一個(gè)8位輸入端口,如果傳感器的傳輸超過(guò)8位數(shù)據(jù),圖像傳感器通常作為從設(shè)備通過(guò)I2C端口控制。底層的協(xié)議是I2C,高層的協(xié)議則由傳感器確定。在這里,圖像傳感器的主時(shí)鐘由MC9328MX21提供。
2 系統(tǒng)的軟件系統(tǒng)設(shè)計(jì)
2.1 搭建交叉編譯環(huán)境
由于嵌入式系統(tǒng)選用的是開源的基于ARM微處理器的系統(tǒng)內(nèi)核ARM-Linux,而在開發(fā)板上沒(méi)有足夠的資源運(yùn)行開發(fā)調(diào)試工具,所以必須首先搭建好交叉編譯調(diào)試環(huán)境。首先,需要通過(guò)在編譯時(shí)指定target=arm-linux生成適合ARM平臺(tái)的binutils,它包括了ld、ar和as等一些生成和處理二進(jìn)制文件的工具。然后,編譯生成GCC(GNU Compiler Collection),它能夠支持多種高級(jí)語(yǔ)言,如C,C++等,需要注意的是,在編譯GCC時(shí)需要ARM-linux內(nèi)核頭文件的支持,所以首先需要配置內(nèi)核#make menuconfig ARCH=ARM來(lái)生成對(duì)應(yīng)ARM內(nèi)核的頭文件,這樣就可以在配置編譯GCC時(shí)通過(guò)with-headers選項(xiàng)指定編譯所需頭文件。最后,還需要編譯生成許多用戶層應(yīng)用都要用到的函數(shù)庫(kù)glibc,所有動(dòng)態(tài)鏈接的程序都要用到它,在編譯時(shí)需要注意的是打開--enable-add-ons選項(xiàng),這個(gè)開關(guān)將打開glibc的附加包,因?yàn)槲覀冃枰玫絣inu-xthreads。這樣,一個(gè)嵌入式ARM-linux下的交叉編譯環(huán)境就已搭建成功。
2.2 編譯制作內(nèi)核及文件系統(tǒng)
通過(guò)make menuconfig配置內(nèi)核選項(xiàng),其中的一些關(guān)鍵設(shè)置包括指定System Type時(shí)打開ARM926T CPUidle、I-Cache 0n和D-Cache,并且由于在進(jìn)行應(yīng)用軟件開發(fā)時(shí)需要ARM-linux內(nèi)核支持frame buffer技術(shù),所以還需要打開Console drivers中的Frame-buffer sup-port。然后,make boot就可以編譯生成定制好的內(nèi)核映像文件Image,將制作好的系統(tǒng)內(nèi)核和文件系統(tǒng)通過(guò)宿主機(jī)的TFTP服務(wù)燒寫進(jìn)開發(fā)板的Flash存儲(chǔ)器。這樣就完成了板上可獨(dú)立運(yùn)行的操作系統(tǒng)的設(shè)計(jì)。
2.3 視頻數(shù)據(jù)的采集、編碼和傳輸?shù)膶?shí)現(xiàn)
這部分的工作是整個(gè)設(shè)計(jì)的核心。MPEG-4在1999年初正式成為國(guó)際標(biāo)準(zhǔn),與之前的標(biāo)準(zhǔn)相比,它更加重視多媒體系統(tǒng)的交互性和靈活性,主要針對(duì)視頻會(huì)議、可視電話的超低比特率編碼等多媒體應(yīng)用。目前在嵌入式系統(tǒng)中,MPEG-4編解碼主要都是通過(guò)專用芯片實(shí)現(xiàn)的,其實(shí)現(xiàn)方法與MPEG-1、MPEG-2的硬件實(shí)現(xiàn)方法類似,將編碼算法固化在芯片的硬件電路中,所以導(dǎo)致它在使用中存在以下缺點(diǎn):
a) 性價(jià)比不高。由于現(xiàn)在MPEG-4編碼技術(shù)還在不斷發(fā)展中,還沒(méi)有一個(gè)真正成熟的算法支持,所以市場(chǎng)上推出的MPEG-4編碼芯片都是在標(biāo)準(zhǔn)基礎(chǔ)上進(jìn)行了修改和簡(jiǎn)化,在性能上與H.263等編碼芯片上沒(méi)有明顯的優(yōu)勢(shì),所以其性價(jià)比不高。
b) 可移植性差。由于各廠商所生產(chǎn)的編碼芯片都在固化時(shí)加入了自己對(duì)編碼算法的改進(jìn)和優(yōu)化,所以在解碼端必須使用對(duì)應(yīng)的專用解碼器,這就導(dǎo)致出現(xiàn)了兼容性的問(wèn)題。
c) 無(wú)可擴(kuò)展性。隨著對(duì)MPEG-4編解碼標(biāo)準(zhǔn)的研究,必然提出許多新的算法及對(duì)原有算法的改進(jìn),但是現(xiàn)有的MPEG-4編碼芯片已將已有的算法固定在了芯片硬件電路中,所以無(wú)法方便地在芯片上進(jìn)行算法的修改及擴(kuò)展。
所以在設(shè)計(jì)該系統(tǒng)時(shí),主要采用了軟件實(shí)現(xiàn)其編解碼,在嵌入式系統(tǒng)中采用軟件實(shí)現(xiàn)編解碼,可以彌補(bǔ)硬件編解碼上的諸多不足,而且便于對(duì)算法本身進(jìn)行研究和改進(jìn)。但是,也需要考慮幾個(gè)問(wèn)題:首先,由于MPEG-4編碼算法運(yùn)算量復(fù)雜,而嵌入式系統(tǒng)的資源有限,所以必須考慮所選平臺(tái)微處理器的運(yùn)算能力;其次,在編碼軟件及數(shù)據(jù)采集硬件的接口部分,由于需要針對(duì)不同的采集硬件,所以需要做許多匯編級(jí)的優(yōu)化。
FFMPEG是一個(gè)音視頻數(shù)據(jù)的采集記錄、編碼及流式傳輸?shù)耐耆鉀Q方案。該項(xiàng)目包括下面組件:
a) FFMPEG是音視頻文件格式轉(zhuǎn)換的命令行方式的工具,同時(shí)支持實(shí)時(shí)的采集編碼TV card數(shù)據(jù)。
b) FFserver可以通過(guò)HTTP/RTSP方式進(jìn)行多媒體數(shù)據(jù)的流式播放。
c) FFplayer是基于FFMPEG庫(kù)和SDL的播放器。
d) libavcodec包括了全部FFMPEG音視頻的編解碼庫(kù),libavformat包括了全部支持的音視頻格式的語(yǔ)法和生成庫(kù)。
FFMPEG庫(kù)支持的編解碼支持格式非常豐富,而且編解碼速度很快;支持指定音視頻捕捉設(shè)備實(shí)時(shí)處理數(shù)據(jù)源并將其存;FFMEPG能夠通過(guò)命令行參數(shù)指定視頻編解碼、格式轉(zhuǎn)換的幀頻、幀大小及比特率、碼率控制緩沖區(qū)的大小;并且,F(xiàn)FMPEG可以通過(guò)激活視頻的高級(jí)選項(xiàng)來(lái)對(duì)編解碼的方式進(jìn)行控制,包括設(shè)置幀內(nèi)編碼、視頻量化標(biāo)度的設(shè)置、設(shè)定p幀以及b與i幀間的qp因子和偏差、運(yùn)動(dòng)估計(jì)及DCT/IDCT算法的選擇,b幀和運(yùn)動(dòng)矢量以及交織編碼方式的使用。對(duì)于視頻捕捉設(shè)備的選擇也可以通過(guò)參數(shù)來(lái)選定,如/dex/video0或DV1394專用通道等。
FFMPEG庫(kù)能夠在多種平臺(tái)上運(yùn)行,包括Linux、Windows和Mac OS等系統(tǒng),在嵌入式系統(tǒng)中,由于嵌入式Linux具有源代碼完全開放、可移植性強(qiáng)和對(duì)網(wǎng)絡(luò)的支持好等特點(diǎn),所以選用了ARM-Linux系統(tǒng),該系統(tǒng)支持這次選用的ARM9架構(gòu)的CPU,而FFMPEG是針對(duì)通用PC的X86架構(gòu)的CPU設(shè)計(jì)的,因此要將FFMPEG移植到ARM9架構(gòu)的系統(tǒng)上。首先需要通過(guò)將其交叉編譯成可在ARM-linux上運(yùn)行的庫(kù)。具體步驟如下。
將下載的最新的FFMPEG源代碼包解壓縮再生成FFMPEG目錄,然后針對(duì)所開發(fā)系統(tǒng)的交叉編譯鏈,通過(guò)修改configure文件來(lái)生成Makefile文件, 然后用make命令通過(guò)讀取生成的Makefile文件來(lái)自動(dòng)編譯生成所需要的FFMPEG庫(kù)文件和可以在ARM開發(fā)板上運(yùn)行的二進(jìn)制可執(zhí)行文件。編譯成功以后就可以通過(guò)宿主機(jī)的NFS服務(wù)將宿主機(jī)安裝到開發(fā)板上,這樣就可以到相關(guān)目錄下測(cè)試所編譯的FFMPEG能否正常地工作:
即將對(duì)音頻文件cat.wav和原始的yuv視頻文件編碼生成cat.mpg,如果沒(méi)有輸入數(shù)據(jù)文件,則音視頻捕捉設(shè)備就將起作用,說(shuō)明所需要的交叉編譯生成的FFM-PEG庫(kù)可以正確地運(yùn)行。
2.4 視頻采集編碼程序的關(guān)鍵技術(shù)
在設(shè)計(jì)視頻采集程序時(shí)主要使用FFMPEG的libavformat和libavcodec這兩個(gè)函數(shù)庫(kù),許多視頻文件格式一般只是定義如何將音視頻流編碼進(jìn)一個(gè)獨(dú)立的文件,而不明確指出其使用的編碼工具,libavformat庫(kù)的功能主要是分析視頻文件的語(yǔ)法格式,并將它從流中分離出原始的音視頻流,libavcodec庫(kù)的功能則是按照流格式處理原始的音視頻流編解碼。
在使用libavformat/libavcodec庫(kù)函數(shù)對(duì)視頻文件進(jìn)行處理時(shí),首先通過(guò)調(diào)用av_register_all()函數(shù)對(duì)其初始化,這個(gè)函數(shù)中定義了所有庫(kù)所能支持的文件格式和編碼器,因此當(dāng)讀取一個(gè)文件時(shí),通過(guò)調(diào)用此函數(shù)來(lái)自動(dòng)使用所對(duì)應(yīng)的格式或者編碼庫(kù)。視頻文件打開則通過(guò)av_open_input_file函數(shù)來(lái)實(shí)現(xiàn):
這個(gè)函數(shù)的最后3個(gè)參數(shù)分別定義了文件的格式、緩沖區(qū)的大小和格式的參數(shù);在這里賦值NULL和0來(lái)指定libavformat庫(kù)函數(shù)自動(dòng)檢測(cè)格式和使用默認(rèn)的緩沖區(qū)的大小。然后就可以讀取文件的流信息:
來(lái)填充AVFormatContext中關(guān)于流區(qū)域的內(nèi)容,接著通過(guò)一個(gè)循環(huán)尋找到第1段視頻流:
這樣就可以讀取視頻流的內(nèi)容來(lái)指定選用的編解碼器并將編解碼器打開:
這里的定義CODEC_CAP_TRUNCATED是指當(dāng)視頻流被分割成小的數(shù)據(jù)包以后,由于每一幀視頻的數(shù)據(jù)量會(huì)發(fā)生變化,這就需要兩個(gè)視頻幀的邊緣與數(shù)據(jù)包的邊緣匹配,因此在這里定義這個(gè)宏來(lái)告訴編碼器該如何處理它。最后調(diào)用avcodec_alloc_frame()函數(shù)來(lái)分配幀緩沖。
在編碼端需要使用libavformat庫(kù)函數(shù)來(lái)讀取這些數(shù)據(jù)包,濾除掉不需要的非視頻流數(shù)據(jù),然后循環(huán)調(diào)用libavcodec庫(kù)函數(shù)GetNextFrame(AVFormatContext *pFormatCtx,AVCodecContext * pCodecCtx,int video-Stream,AVFrame * pFrame)來(lái)處理每幀數(shù)據(jù)進(jìn)行編解碼。
視頻采集端采用從Video4Linux視頻設(shè)備源中捕捉視頻幀,Video4Linux是Linux下用于獲取音頻和視頻的API接口,現(xiàn)有的Video4Linux有v41和v412兩個(gè)版本,我們采用v4l進(jìn)行編程,在Linux下,將所有外沒(méi)都看做一種特殊的文件,稱之為設(shè)備文件,因此利用v4l API獲取視頻圖像可以通過(guò)調(diào)用open、ioctl等函數(shù),像對(duì)普通文件一樣對(duì)硬件進(jìn)行初始化、設(shè)置硬件屬性和調(diào)用硬件中斷等操作。在打開視頻采集設(shè)備后,分別通過(guò)ioctl(vd->fd,VIDIOCGCAP,&(vd->ca-pability))函數(shù)的VIDIOCGCAP控制命令,來(lái)獲取關(guān)于視頻采集設(shè)備所能顯示的最大圖像大小,信號(hào)源的通道數(shù)和通過(guò)ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))的VIDIOCGPICT來(lái)獲取一些關(guān)于圖像的亮度、對(duì)比度等信息。Video4Linux方式獲取視頻圖像的方式有overlay和mmap兩種,在這里采用了MMAP方式,MMAP方式允許直接將設(shè)備內(nèi)存映射到用戶進(jìn)程的地址空間中,這樣就可以直接在進(jìn)程中讀寫內(nèi)存來(lái)控制設(shè)備。在使用libavformat/libavcodec庫(kù)從Vide-o4Linux視頻設(shè)備源中捕捉視頻幀時(shí)需要調(diào)用av_open_input_file()函數(shù),因此,最后還需要修改此函數(shù)中的設(shè)備屬性配置,使之與我們所選用的沒(méi)備相對(duì)應(yīng)。
3 測(cè)試結(jié)果及展望
在這里使用了ffserver流媒體服務(wù)端組件來(lái)實(shí)現(xiàn)流媒體傳輸,首先需要配置ffserver.conf文件中關(guān)于服務(wù)端主機(jī)的端口號(hào)、傳輸帶寬、延遲,流媒體文件屬性等信息。然后啟動(dòng)ffserver讀取配置文件,就可以在接收端通過(guò)WMP(Windows Media Player)輸入服務(wù)端URL看到實(shí)時(shí)采集的視頻圖像。經(jīng)測(cè)試,目前該嵌入式流媒體服務(wù)器在傳輸MPEG-4視頻時(shí)的幀率可以達(dá)到20幀/s,接收端觀察圖像流暢,畫面清晰。
本文提出了一種基于ARM9架構(gòu)MC9328MX21的嵌入式系統(tǒng)上實(shí)現(xiàn)MPEG-4流媒體視頻采集傳輸系統(tǒng),通過(guò)在ARM-Linux操作系統(tǒng)下移植libavformat/libavcode庫(kù),利用該函數(shù)庫(kù)良好的可移植性和Video4Linux完成了本地視頻圖像的采集、編碼等功能,并向網(wǎng)絡(luò)發(fā)送流媒體打包數(shù)據(jù)。該系統(tǒng)具有實(shí)時(shí)性好、可移植性強(qiáng)、低功耗和可遠(yuǎn)程移動(dòng)控制嵌入式系統(tǒng)的特點(diǎn),并且采用軟件實(shí)現(xiàn)其主要功能,有利于系統(tǒng)的二次開發(fā)及升級(jí),其應(yīng)用范圍和前景將非常廣闊。