基于A(yíng)RM11的無(wú)線(xiàn)視頻監控系統
發(fā)送端主要過(guò)程如下:
(1)創(chuàng )建RTP 會(huì )話(huà)并設置目標地址。調用Create方法得到RTP 會(huì )話(huà)實(shí)例,然后調用AddDestination 方法設置目標IP 以及目標端口號。
(2)獲得數據,調用Get_Data()函數得到。
(3)發(fā)送數據,通過(guò)SendPacket()方法實(shí)現。
接收端主要過(guò)程如下:
(1)創(chuàng )建RTP 會(huì )話(huà)。調用Create 方法來(lái)創(chuàng )建一個(gè)會(huì )話(huà)實(shí)例,并且在創(chuàng )建會(huì )話(huà)的同時(shí)設置端口號,要與發(fā)送端的端口號保持一致。
(2)接受RTP 數據。調用RTPSession 類(lèi)的PollData()方法接收數據。
(3)保存RTP 數據報。通過(guò)創(chuàng )建了一個(gè)指針數組,里面存放的是RTP 數據報的指針,只要將剛接收到RTP 數據報的指針賦給這個(gè)指針數組即可,這樣可以節省數據拷貝的時(shí)間。
(4)判斷是否接收完成,如果沒(méi)有,則跳轉到第b 步,否則接收端程序退出。
4.2 視頻數據的解碼和顯示
由于接收到的數據是經(jīng)H264 編碼的數據,因此,先要對該數據進(jìn)行解碼,然后才能顯示。而在服務(wù)器端,對視頻數據解碼用到FFmpeg.FFmpeg 是一個(gè)開(kāi)源免費跨平臺的視頻和音頻流方案,屬于自由軟件。
解碼時(shí)主要涉及FFmpeg 下的libavcodec 庫、libswscale庫和libavformat 庫,其中第一個(gè)庫是一個(gè)包含了所有FFmpeg 音視頻編解碼器的庫,第二個(gè)庫是格式轉化庫,因為解碼后的數據是YUV420 格式,而要在計算機上顯示該數據,則需要的是RGB 格式的,該庫功能就是把YUV420 格式轉化成RGB 格式,第三個(gè)庫是一個(gè)包含了所有的普通音視格式的解析器和產(chǎn)生器的庫。
4.2.1 初始化解碼線(xiàn)程
(1) 注冊全部的文件格式和編解碼器,調用av_register_all()函數完成注冊。
(2) 設置AVFormatContext 結構體。該結構體是FFmpeg 格式轉換過(guò)程中實(shí)現輸入和輸出功能,保存相關(guān)數據的主要結構,通過(guò)av_open_input_file 函數設置該結構體。
(3) 檢查視頻流的信息,通過(guò)調用av_find_stream_info(pFormatCtx)函數,pFormatCtx->streams 就填充了正確的視頻流信息,pFormatCtx 類(lèi)型是AVFormatContext.
(4) 得到編解碼器上下文,pCodecCtx= pFormatCtx -> streams[videoStream]->codec,pCodecCtx 指針指向了流中所使用的關(guān)于編解碼器的所有信息。
(5) 打開(kāi)解碼器,先通過(guò)avcodec_find_decoder 函數找到相應解碼器,然后調用avcodec_open 函數打開(kāi)解碼器。
(6) 申請內存用來(lái)存放解碼數據, 通過(guò)調用avcodec_alloc_frame 函數實(shí)現,由于解碼的數據是YUV420 格式的,因此還需要將該數據轉換成RGB 格式,因此,再次調用avcodec_alloc_frame 申請內存用來(lái)存放RGB 格式數據。
(7) 申請內存用來(lái)存放原始數據,因為H264 解碼時(shí),對于P 幀需要參考前面一個(gè)關(guān)鍵幀或P 幀,而B(niǎo)幀需要參考前后幀,因此需要存放原始數據,首先,用avpicture_get_size 來(lái)獲得需要的大小,然后調用av_malloc 函數申請內存空間。
(8) 通過(guò)調用avpicture_fill 函數將幀和新申請的內存結合起來(lái)。
(9) 創(chuàng )建格式轉換上下文,通過(guò)img_convert_ctx=sws _getContext(src_w, src_h,src_pix_fmt, dst_w, dst_h,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL,NULL)方法實(shí)現。其中,src_w 表示源圖像的寬度,src_h 表示源圖像的高度,src_pix_fmt 表示源圖像的格式,dst_w 表示目標圖像的寬度,dst_h 表示目標圖像的高度,PIX_FMT_RGB24 表示目標圖像的格式。
4.2.2 對數據進(jìn)行H264 解碼
(1) 獲得需要解碼的一幀數據,由于前面接收端線(xiàn)程已經(jīng)把接收到的數據存放在一個(gè)指針數組中,因此,解碼線(xiàn)程只需要從指針數據中獲取數據即可。
(2) 解碼數據。調用解碼函數avcodec_ decode_video(pCodecCtx , pFrame , finished , encodedData,size)來(lái)解碼視頻文件。其中,參數pCodecCtx是前面得到視頻流編碼上下文的指針;參數pFrame存儲解碼后的圖片的位置,參數finished 用來(lái)記錄已完成的幀數;參數encodedData 是輸入緩沖區指針,指向要解碼的原始數據;參數size 是輸入緩沖區的大小。
(3) 將已解碼的視頻數據YUV420 格式轉換成RGB 格式,通過(guò)調用sws_scale()函數實(shí)現格式轉換。
4.2.3 視頻數據的顯示
本系統使用QT 下的QImage 顯示視頻數據,由于QImage 能夠存取單個(gè)像素,這樣在顯示前一幀圖像的時(shí)候,將該圖像保存下來(lái),當顯示后一幀圖像的時(shí)候,如果該像素值與前一幀相同,則不必修改該值,從而節省了大量的時(shí)間,即哪里變修改哪里,顯示過(guò)程的具體步驟如下:
(1) 取得已解碼的視頻數據,且該數據是RGB 格式的。
(2) 循環(huán)取得視頻數據的R 分量、G 分量、B 分量。
(3) 判斷該點(diǎn)的像素值是否與前一幀對應位置的像素值相同,若相同,跳轉到第2 步,否則,保存該像素值。
(4) 對取得的RGB 各自分量,構造該像素點(diǎn)的顏色值,通過(guò)調用qRGB(R,G,B)構造方法實(shí)現。
(5) 設置相應點(diǎn)的像素值,首先生成QImage 類(lèi)的對象,然后調用該類(lèi)的setPixel(x,y,rgb)。其中,x 是圖像的x 坐標值,y 是圖像的y 坐標值,rgb 是該點(diǎn)的顏色值。
(6) 顯示圖像,通過(guò)調用update()方法,該方法會(huì )觸發(fā)繪畫(huà)事件,因此,在繪畫(huà)事件里,寫(xiě)入顯示圖像代碼,即可顯示剛生成的QImage 對象,通過(guò)調用drawImage()方法繪制圖像。
5 結論
本系統在視頻圖像采集時(shí),為了降低數據量,采用YUV420 的采樣格式。視頻數據編碼采用H264 硬編碼方式,極大地提高了編碼速度。而在無(wú)線(xiàn)網(wǎng)絡(luò )傳輸時(shí),考慮到丟包問(wèn)題,將編碼數據進(jìn)行拆包然后發(fā)送,降低了丟包率。經(jīng)測試,本系統采集一幅OV9650攝像頭拍攝的且分辨率為320X240 的圖像,經(jīng)H264硬編碼,編碼后的圖像數據大致為5KB 左右,降低了數據傳輸量,并且硬編碼每秒可編碼25 幀圖像數據,達到實(shí)時(shí)視頻數據編碼的要求。對于WI-FI 無(wú)線(xiàn)網(wǎng)絡(luò )的傳輸率一般在11-54Mbps 左右,因此,該無(wú)線(xiàn)網(wǎng)絡(luò )可以滿(mǎn)足實(shí)時(shí)傳輸視頻的需求。本系統構建了高實(shí)時(shí)性,低成本,低功耗的數字化無(wú)線(xiàn)視頻監控平臺,在該平臺基礎上,可以搭建各種各樣的應用,比如,路況實(shí)時(shí)監控,人臉識別,倉庫報警等應用,該系統具有一定的實(shí)用價(jià)值。
評論