郝 朝,王 灝
(中國(guó)飛行試驗(yàn)研究院,陜西 西安 710089)
在飛行試驗(yàn)中,實(shí)時(shí)監(jiān)控是保障飛行安全和提高飛行效率的一個(gè)關(guān)鍵環(huán)節(jié),要求實(shí)時(shí)查看飛行器的位置姿態(tài)信息和設(shè)備的工作狀態(tài)。機(jī)載視頻影像能夠以最為直觀與準(zhǔn)確的方式描述飛機(jī)當(dāng)前的工作狀態(tài),為地面飛行指揮人員和試飛工程師提供及時(shí)、豐富的信息,對(duì)于保障飛行安全、提高試飛效率有不可替代的作用[1]。
在某型飛機(jī)的實(shí)時(shí)監(jiān)控中,既有傳統(tǒng)的PCM數(shù)據(jù)遙測(cè),也有網(wǎng)絡(luò)電臺(tái)遙測(cè)。傳統(tǒng)的視頻遙測(cè)是將數(shù)字視頻信號(hào)以PCM流的形式傳輸至地面進(jìn)行解析[2]。在該型機(jī)上,由于任務(wù)需求,在機(jī)上加裝網(wǎng)絡(luò)攝像頭,通過(guò)網(wǎng)絡(luò)電臺(tái)以RTP/RTCP[3-4]網(wǎng)絡(luò)數(shù)據(jù)包的形式進(jìn)行H.264視頻網(wǎng)絡(luò)化遙測(cè)傳輸。在該型機(jī)上,視頻數(shù)據(jù)為網(wǎng)絡(luò)數(shù)據(jù)包,現(xiàn)有視頻解析軟件無(wú)法滿足型號(hào)需求。
根據(jù)以上型號(hào)任務(wù)需求,為了有效保證試飛安全,設(shè)計(jì)了基于RTP/RTCP協(xié)議的機(jī)載網(wǎng)絡(luò)視頻實(shí)時(shí)監(jiān)控系統(tǒng)。通過(guò)UDP組播[5-6]接收地面網(wǎng)絡(luò)電臺(tái)發(fā)送的RTP協(xié)議數(shù)據(jù)包,對(duì)其進(jìn)行解析還原成一幀圖像供FFmpeg[7-8]解碼,然后利用SDL[9-10]進(jìn)行顯示。
機(jī)載網(wǎng)絡(luò)化視頻遙測(cè)監(jiān)控整體架構(gòu)如圖1所示。
圖1 系統(tǒng)整體架構(gòu)
機(jī)載網(wǎng)絡(luò)攝像頭經(jīng)過(guò)機(jī)載網(wǎng)絡(luò)交換機(jī)同時(shí)傳輸8 M大碼流(1 920*1 080)和1 M小碼流(640*352)兩種格式的視頻,其中小碼流用于遙測(cè)視頻實(shí)時(shí)監(jiān)控,而大碼流高清視頻則用于機(jī)載記錄。小碼流經(jīng)過(guò)機(jī)載網(wǎng)絡(luò)電臺(tái)通過(guò)機(jī)載天線發(fā)射出來(lái),地面天線接收后經(jīng)過(guò)地面網(wǎng)絡(luò)電臺(tái)將RTP/RTCP數(shù)據(jù)包以UDP組播的方式發(fā)送出去,客戶端進(jìn)行視頻解析顯示。通過(guò)對(duì)機(jī)載記錄數(shù)據(jù)進(jìn)行卸載處理后進(jìn)行視頻回放。該系統(tǒng)基于FFmpeg和SDL,主要工作流程如下:接收經(jīng)RTP協(xié)議封裝的H.264 NALU數(shù)據(jù)包后,首先去除RTP封裝,封裝的NALU被取出后,根據(jù)數(shù)據(jù)類型,把NALU還原成完整的一幀交由FFmpeg解碼處理,被解碼后的YUV[11-12]數(shù)據(jù)通過(guò)SDL進(jìn)行實(shí)時(shí)顯示。
RTP(real-time transfer protocol)提供端對(duì)端實(shí)時(shí)媒體數(shù)據(jù)傳輸協(xié)議,其配套協(xié)議是RTCP(real-time transfer control protocol)用來(lái)監(jiān)控實(shí)時(shí)數(shù)據(jù)的傳輸,通過(guò)組播和點(diǎn)播傳送實(shí)時(shí)數(shù)據(jù)。RTP使用偶數(shù)端口號(hào)接收發(fā)送數(shù)據(jù),相應(yīng)的RTCP則使用相鄰的下一位奇數(shù)端口號(hào),構(gòu)成一個(gè)UDP端口對(duì)。
RTP數(shù)據(jù)包由兩部分組成:包頭和有效載荷。包頭為12字節(jié),結(jié)構(gòu)如圖2所示。
圖2 RTP包頭格式
RTCP數(shù)據(jù)包的格式如圖3所示。
圖3 RTCP數(shù)據(jù)包格式
利用NTP時(shí)間戳、RTCP數(shù)據(jù)包和RTP包中的RTP時(shí)間戳計(jì)算得到當(dāng)前RTP包的絕對(duì)時(shí)間。計(jì)算步驟如下:
(1)由NTP時(shí)間戳計(jì)算得到RTCP包的PTP時(shí)間PTPRTCP;
(2)計(jì)算RTP包與RTCP數(shù)據(jù)包的RTP時(shí)間戳差△RTP;
(3)計(jì)算當(dāng)前RTP包的PTP時(shí)間:
PTPRTP=PTPRTCP+△RTP
原始H.264的NALU由[Start Code][NALU Header][NALU Payload]三部分組成,其中起始碼用于標(biāo)識(shí)一個(gè)NALU的開(kāi)始,必須是“0x00 00 00 01”或者“0x 00 00 01”[13]。NALU頭僅一個(gè)字節(jié),其后是NALU內(nèi)容。
H.264的NALU封裝成RTP的方式有三種[14]:
(1)單一NALU模式;一個(gè)RTP包僅由一個(gè)完整的NALU組成;這種情況下只需要去掉RTP包頭加上NALU起始碼即可送去解碼。
(2)組合封包模式:一個(gè)RTP包由多個(gè)NALU組成。
(3)分片封包模式:將一個(gè)NALU封裝成多個(gè)RTP包。數(shù)據(jù)包格式如圖4所示。
圖4 FU-A分片封包RTP數(shù)據(jù)包格式
當(dāng)FU指示字節(jié)的Type為28時(shí),代表為FU-A分片。
S:起始位(1 bit),當(dāng)設(shè)置為1時(shí),代表分片NAL單元的開(kāi)始。
E:結(jié)束位(1 bit),當(dāng)設(shè)置為1時(shí),代表分片NAL單元的結(jié)束。
RTP數(shù)據(jù)包解包邏輯流程如圖5所示。
圖5 RTP協(xié)議解包邏輯流程
在獲得完整的NALU后,將其送入FFmpeg緩存進(jìn)行解碼,解碼流程為:首先對(duì)解碼進(jìn)行初始化,注冊(cè)容器及編碼類型,然后查找解碼器,分配解碼器上下文,分配解碼幀緩沖,最后循環(huán)對(duì)NALU進(jìn)行解碼得到Y(jié)UV圖像數(shù)據(jù)。
FFmpeg將NALU解碼成YUV數(shù)據(jù)后送到SDL進(jìn)行顯示。SDL顯示YUV數(shù)據(jù)流程為:首先對(duì)SDL進(jìn)行初始化,利用控件創(chuàng)建SDL顯示窗口,然后利用控件創(chuàng)建SDL顯示窗口,創(chuàng)建紋理用于顯示YUV數(shù)據(jù),循環(huán)將處理后的YUV數(shù)據(jù)設(shè)置為紋理的像素?cái)?shù)據(jù),將紋理數(shù)據(jù)復(fù)制給渲染目標(biāo),顯示畫(huà)面。
YUV是一種顏色編碼方法,將亮度信息(Y)與色彩信息(UV)分離。YUV分為三個(gè)分量,Y表示明亮度,也就是灰度值;U和V表示色度,作用是描述影像顏色及飽和度。一個(gè)像素點(diǎn)對(duì)應(yīng)一個(gè)Y。YUV格式分為平面(planar)格式和打包(packed)格式。平面格式使用3個(gè)數(shù)組分開(kāi)存放YUV三個(gè)分量;打包格式將YUV分量存放在同一個(gè)數(shù)組中,通常是幾個(gè)相鄰的像素組成一個(gè)宏像素(macro-pixel)。YUV碼流的存儲(chǔ)方式與其采樣的方式相關(guān),主流的采樣方式有三種:YUV4∶4∶4(Y與UV分量一一對(duì)應(yīng)),YUV4∶2∶2(每?jī)蓚€(gè)Y共用一組UV分量)和YUV4∶2∶0(每2×2個(gè)Y共用一組UV分量)。FFMPEG解碼之后的數(shù)據(jù)為YUV420p格式,屬于平面格式。
圖像旋轉(zhuǎn)的關(guān)鍵在于由源畫(huà)面的大小、旋轉(zhuǎn)角度確定目標(biāo)畫(huà)面的大小,然后計(jì)算目標(biāo)畫(huà)面每個(gè)像素YUV分量在源畫(huà)面中的位置。假設(shè)源畫(huà)面分辨率為w*h,順時(shí)針旋轉(zhuǎn)90°,則目標(biāo)畫(huà)面分辨率為h*w,YUV分量與源畫(huà)面對(duì)應(yīng)關(guān)系如下:
Yn(i,j)=Yo(h-j-1,i)
Un(k)=Uo(w*h/4-w/2*(k%h/2+1)+k/h/2)
Vn(k)=Vo(w*h/4-w/2*(k%h/2+1)+k/h/2)
在數(shù)據(jù)包發(fā)送較快的情況下,由于接收端不僅要完成接收碼流,還要進(jìn)行分析、解碼、顯示,這個(gè)處理需要較長(zhǎng)的過(guò)程,如果接收端順序執(zhí)行這個(gè)過(guò)程,會(huì)出現(xiàn)視頻畫(huà)面延遲的現(xiàn)象,另外無(wú)法保證數(shù)據(jù)包的完整接收,出現(xiàn)丟包等情況,導(dǎo)致解碼花屏、程序崩潰等嚴(yán)重錯(cuò)誤。由于網(wǎng)絡(luò)不穩(wěn)定,接收到的數(shù)據(jù)可能時(shí)快時(shí)慢,這直接導(dǎo)致解碼的不穩(wěn)定和視頻播放的不連續(xù)。
針對(duì)此問(wèn)題,采用多線程并發(fā)[15-16]處理機(jī)制予以解決。分別針對(duì)數(shù)據(jù)接收、解包、解碼和顯示均開(kāi)辟單獨(dú)的線程,設(shè)置緩沖區(qū)存放接收到大量的碼流,同時(shí)為視頻數(shù)據(jù)分析解碼提供數(shù)據(jù)及寫(xiě)入和讀出的過(guò)程,采用先入先出的隊(duì)列進(jìn)行處理。將接收到的數(shù)據(jù)暫時(shí)存放在隊(duì)列中,接著去接收下一包數(shù)據(jù),這樣大大提高了接收效率同時(shí)避免由于程序缺陷導(dǎo)致的丟包問(wèn)題。
設(shè)置三個(gè)緩沖區(qū):RTP數(shù)據(jù)包緩沖區(qū);NALU緩沖區(qū);YUV數(shù)據(jù)緩沖區(qū)。網(wǎng)絡(luò)接收線程和RTP解包線程均需對(duì)RTP數(shù)據(jù)包緩沖區(qū)進(jìn)行操作,RTP解包線程與解碼線程均需對(duì)NALU緩沖區(qū)進(jìn)行操作,解碼線程與顯示線程均需對(duì)YUV數(shù)據(jù)緩沖區(qū)進(jìn)行操作。因此每?jī)蓚€(gè)線程均需要進(jìn)行線程間同步與互斥處理。
網(wǎng)絡(luò)遙測(cè)視頻實(shí)時(shí)播放界面如圖6所示。設(shè)置組播IP地址和端口號(hào),實(shí)現(xiàn)接收并顯示相應(yīng)的網(wǎng)絡(luò)攝像頭視頻。根據(jù)機(jī)上攝像頭安裝位置限制設(shè)置圖像的旋轉(zhuǎn)角度,實(shí)際應(yīng)用效果表明該軟件能夠?qū)TP數(shù)據(jù)包進(jìn)行實(shí)時(shí)解析,采用FFmpeg和SDL能夠?qū)崿F(xiàn)視頻圖像的解碼與顯示。
圖6 網(wǎng)絡(luò)遙測(cè)視頻實(shí)時(shí)解析界面
文中論述了機(jī)載網(wǎng)絡(luò)視頻實(shí)時(shí)解析軟件的設(shè)計(jì)與實(shí)現(xiàn),對(duì)網(wǎng)絡(luò)電臺(tái)發(fā)送的RTP數(shù)據(jù)包進(jìn)行解析,采用具有良好解碼性能的FFmpeg和音視頻性能的SDL實(shí)現(xiàn)對(duì)機(jī)載網(wǎng)絡(luò)視頻的實(shí)時(shí)解析與顯示。實(shí)際應(yīng)用效果表明,解碼播放性能良好,實(shí)時(shí)性滿足監(jiān)控要求。軟件采用模塊化設(shè)計(jì)、多線程等設(shè)計(jì)思路,提高了軟件的執(zhí)行效率,有效保證了試飛安全。