0 引言
隨著視頻編解碼技術(shù),、計算機網(wǎng)絡(luò)技術(shù)、數(shù)字信號處理技術(shù)和嵌入式系統(tǒng)的發(fā)展,,以嵌入式網(wǎng)絡(luò)視頻服務(wù)器為核心的遠程視頻監(jiān)控系統(tǒng)開始在市場上嶄露頭角,。該系統(tǒng)把攝像機輸出的模擬視頻信號通過內(nèi)置的嵌入式視頻編碼器直接轉(zhuǎn)換成視頻流,通過計算機網(wǎng)絡(luò)傳輸出去,。嵌入式網(wǎng)絡(luò)視頻服務(wù)器具備視頻編碼處理,、網(wǎng)絡(luò)通信、系統(tǒng)控制等強大功能,,直接支持網(wǎng)絡(luò)視頻傳輸和網(wǎng)絡(luò)管理,,使得監(jiān)控范圍達到前所未有的廣度。在遠程視頻監(jiān)控系統(tǒng)中,,攝像頭獲取的原始視頻流在傳輸之前需要壓縮,,而FFmpeg可以將原始視頻壓縮為H264格式視頻流,H264是一種被廣泛使用的高精度視頻的錄制,、壓縮和發(fā)布格式,,因此采用FFmpeg來實現(xiàn)。
1 系統(tǒng)方案
系統(tǒng)是在S3C2440平臺上運行嵌入式Linux系統(tǒng),,使用CMOS攝像頭OV9650獲取實時視頻圖像數(shù)據(jù),,采用H264標準通過FFmpeg原始視頻進行壓縮編碼成視頻流,通過網(wǎng)絡(luò)傳輸,,用戶在接收處理端經(jīng)過FFmpeg解碼之后,,使用OpenCV顯示播放即可實時查看遠程視頻圖像。
系統(tǒng)由兩部分組成:采集發(fā)送端和接收處理端,,采用Client/Server設(shè)計模式來實現(xiàn)兩者之間的相互通信,,由接收處理端向采集發(fā)送端發(fā)送控制信號,,采集發(fā)送端開啟攝像頭進行視頻數(shù)據(jù)采集,采集的原始視頻數(shù)據(jù)是yuv422格式,,經(jīng)過FFmpcg編碼壓縮成H.264格式視頻流,,經(jīng)通信網(wǎng)絡(luò)傳輸?shù)浇邮仗幚矶耍唤邮仗幚矶私邮盏揭曨l流數(shù)據(jù)后,,經(jīng)FFmpeg解碼,,通過OpenCV進行顯示。采集發(fā)送端視頻數(shù)據(jù)采集和發(fā)送采用三星公司的具有ARM920T內(nèi)核的S3C2440作為嵌入式微控制器,,接收處理端采用普通電腦,。系統(tǒng)方案如圖1所示。
2 采集發(fā)送端
采集發(fā)送端主要包括嵌入式Linux平臺和攝像頭兩部分,,嵌入式Linux平臺需要搭建交叉編譯環(huán)境,,而攝像頭需要驅(qū)動程序才能正常工作。
嵌入式Linux平臺采用三星公司的S3C2440A處理器為硬件平臺,,S3C2440A處理器是一款基于ARM920T內(nèi)核的16/32bit嵌入式處理器,,主頻
400MHz,最高可達533MHz,支持30/130/200萬像素CMOS攝像頭,,支持linux2.4和Wince4.2雙操作系統(tǒng),,適合應(yīng)用于對功率和成本都較敏感的嵌入式系統(tǒng)場合。
攝像頭采用Omni Visio公司生產(chǎn)的CMOS攝像頭OV9650,,具有高敏感度,、低功耗,高分辨率(最高1300X1028 pixels),,支持大量常用的圖像格式、支持自動圖像控制等優(yōu)點,。在接口上能夠保持與S3C2440的一致性,。輸出圖像最大為130萬像素,輸出圖像格式包括SXGA,,VGA,,QVG A,CIF,,QCIF等,,并可以輸出不同尺寸的圖像。對于不同的輸出圖像格式,,最高幀率可以不同,,最高可達120f/s,輸出的8位數(shù)據(jù)格式包括YUV/YCbCr(4:2:2),、GRB(4:2:2),、原始RGB數(shù)據(jù)3種,。
2.1 建立嵌入式Linux平臺
建立嵌入式Linux系統(tǒng)的基本流程:首先在宿主機上建立交叉編譯環(huán)境,然后移植Linux的引導程序到目標板,,最后構(gòu)建嵌入式Linux系統(tǒng)并移植到目標板,。構(gòu)建嵌入式Linux系統(tǒng)主要包括對內(nèi)核進行裁剪和配置,根據(jù)實際的硬件系統(tǒng)進行內(nèi)核和外設(shè)驅(qū)動程序的移植開發(fā),,以及構(gòu)建Linux的根文件系統(tǒng),。
2.2 攝像頭驅(qū)動配置
CMOS攝像頭驅(qū)動以MODULES的形式編寫,因為MODULES形式的驅(qū)動可動態(tài)加載到Linux內(nèi)核,。
加載驅(qū)動程序后,,就可以像操作普通文件一樣對攝像頭進行操作。如:定義intm_filev412,,通過m_filev412=open(“/dev/camera” O_RDWR)打開攝像頭,,通過read(fd,&inyuv422,D SIZE)讀取攝像頭的視頻數(shù)據(jù)到數(shù)組inyuv422中,通過closc(m_filev412)關(guān)閉攝像頭,。有了視頻數(shù)據(jù)后,,就可以通FFmpeg進行編碼。
2. 3 FFmpeg編碼
2.3.1 FFmpeg簡介
FFmpeg是一個開源免費跨平臺的視頻和音頻流方案,,屬于自由軟件,,采用LGPL或GPL許可證(依據(jù)所你選擇的組件),是一個集錄制,、轉(zhuǎn)換,、音/視頻編解碼功能為一體的、完整的開源解決方案,。FFmpeg的開發(fā)基于Linux操作系統(tǒng),,也可在大多數(shù)操作系統(tǒng)中編譯和使用。FFmpeg支持MPEG,、DivX,、MPEG4、AC3,、DV,、FLV等40多種編碼,AVI,、MPEG,、OGG、Matroska,、ASF等90多種解碼,;TCPMP、VLC,、MPlayer等開源播放器都用到了FFmpeg,。
FFmpeg中FF是指Fast Forward,。
2.3.2 編碼
OV9650攝像頭輸出的數(shù)據(jù)為yuv422格式,而FFmpeg編碼需要輸入yuv420格式數(shù)據(jù),,因此在編碼之前需要先將yuv422格式數(shù)據(jù)轉(zhuǎn)化為yuv 420格式,。FFmpeg中的函數(shù)sws_scale()可以實現(xiàn)這個過程。
在使用FFmpeg編碼之前,,首先需要對FFmpeg庫進行初始化,,注冊所有的編解碼器以及文件格式,設(shè)置編碼器碼率,、幀速率,、編碼像素格式等參數(shù),然后尋找編碼器并打開,,打開編碼器之后才可以進行編碼,。通過設(shè)置結(jié)構(gòu)體AVCodecContext中的各個成員參數(shù)來完成參數(shù)的設(shè)置過程,例如通過設(shè)置AVCodecContext->bit_rate,,AVCodecContext->width,,AVCodecContcxt->height等可以設(shè)置碼率,寬度和高度等,,通過設(shè)置AVCodecContext->pix_fmt=PIX_FMT_YUV420P設(shè)置YUV420像素格式,。編碼核心函數(shù)是avcodec_encode_video()。系統(tǒng)每采集一幀數(shù)據(jù),,就送給avcodec_encode_video()函數(shù)編碼成H.264視頻流,。其編碼流程如圖2所示。
下面對編碼流程的各個步驟中主要函數(shù)的作用進行詳細介紹:
1)av_register_all():注冊庫中含有所有文件格式和編解碼器,,沒有這一步將無法打開編解碼器,。
2)av_open_imput_file():打開攝像頭視頻文件。
3)av_find_stream_info():尋找視頻流,。
4)av_find_encoder():尋找編碼器,,編碼器參數(shù)需在pCodec中初始化,參數(shù)的初始化很重要,,對編碼的圖像質(zhì)量有很大影響。
pCodec=avcodec_find_encoder (CODEC_ID_H264),;//尋找H.264格式編碼器
5)avcodec_alloc_frame():為編碼幀分配內(nèi)存,。
pFrame=avcodec_alloc_frame();//pFrame為AVFrame格式
6)avcodec_open():打開編碼器,。
7)av_read_frame():從視頻流中讀取一幀視頻數(shù)據(jù),。
8)avcodec_encode_video():編碼一幀視頻數(shù)據(jù)。
9)avcodec_close():關(guān)閉編碼器,。
10)avformat_close_mput file():關(guān)閉視頻攝像頭文件,。
3 接收處理端
接收處理端可以與任意一個采集發(fā)送端進行連接通信,。連接后可以接收采集發(fā)送端發(fā)送的視頻數(shù)據(jù),經(jīng)過FFmpeg解碼后顯示,。
3.1 FFmpeg解碼
用FFmpeg解碼的流程與編碼的流程大致相同,,只是解碼的核心函數(shù)為avcodec_decode_video()。接收處理端接收到一幀數(shù)據(jù)后,,通過avpicture_fill()存儲到AVFrame格式的內(nèi)存空間中,,然后再使用avcodec_decode_video()函數(shù)進行解碼。其解碼流程如圖3所示:
3.2.視頻顯示
FFmpeg對H.264解碼出來格式是YUV(.i420)格式,,需要轉(zhuǎn)換成RGB(.rgb24)格式顯示,,使用FFMPEG中的sws_scalc()函數(shù)可以實現(xiàn)格式轉(zhuǎn)換。
顯示視頻采用的是OpenCV,。顯示的核心函數(shù)是cVShowImage(char* name,,lpllmage* dst),將得到的RGB(.rgb24)格式數(shù)據(jù)轉(zhuǎn)換為OpenCV格式的lpllmage數(shù)據(jù),,然后顯示在監(jiān)控窗口上,,如圖4所示:
4 結(jié)束語
隨著視頻壓縮技術(shù)的發(fā)展成熟,嵌入式視頻監(jiān)控逐漸在監(jiān)控領(lǐng)域占有重要地位,。以S3C2440為嵌入式硬件平臺,,通過攝像頭采集數(shù)據(jù),在嵌入式Linux與Windows操作系統(tǒng)相結(jié)合的跨平臺上,,實現(xiàn)FFmpeg的編解碼,,為實際嵌入式視頻監(jiān)控系統(tǒng)的視頻壓縮傳輸設(shè)計,提供了一種可行的方法,。