,,
(中國艦船研究設計中心,武漢 430064)
視頻監視系統以其直觀、準確、及時和信息內容豐富而廣泛應用于許多場合。在船舶領域,視頻監視系統在安全防范,災害發現與確認,信息獲取等方面也有著普通傳感器無法比擬的優勢[1-2]。
在災害發生時,通過的視頻,可以確切地獲知船舶的安全狀態。直觀的信息有利于指揮員能夠快速準確地處理分析現場情況,有效地組織各種力量采取應對措施,減輕甚至消除災害所帶來的影響,將艦船維持在正常或接近正常的狀態。
DirectShow是一個處理Windows平臺上各種格式的媒體文件的播放、音視頻采集等高性能要求的成熟技術。DirectShow不但能支持多種音視頻編解碼器和多種媒體類型并提供高品質的媒體流解碼和回放,而且能夠封裝硬件差異驅動接口[3],及用與設備無關的方法提供設備相關的性能。基于DirectShow以上的優勢,本文采用DirectShow開發船舶監視系統。
DirectShow 是一個基于COM(組件對象模型)系統的一個開放性的應用框架,由許多模塊化的軟件組件組成[4]。DirectShow系統功能見圖1。
DirectShow系統位于Ring3特權級別應用層,它使用Filter Graph模型來管理整個數據流的處理過程。Filter是用于處理數據的功能模塊,它在Filter Graph中按一定的順序協同工作,Filter分為3類:Source Filter、Transform Filter和Rendering Filter[5]。

圖1 DirectShow系統
Source Filter主要負責獲取數據和前期的處理,并把數據往下傳輸。數據源可以是文件、采集卡、數字攝像機等。Transform Filter主要負責數據格式轉換,并把數據繼續往下傳輸。完成數據的分離與合成、解碼盒編碼等。Rendering Filter主要負責將數據傳輸給顯卡、聲卡等硬件設備進行多媒體的播放,并把數據流轉換成文件進行存儲。
Filter包含一個或多個Pin,Filter通過Pin進行連接,使數據構成一條順序的鏈路。由于Source Filter和Rendering Filter分別為數據流的起點和終點,所以Source Filter不包含輸入Pin,Rendering Filter不包含輸出Pin。
開發Filter,選擇合適的父類,不但能減少編程和調試的工作量,而且能有效地降低出錯率。DirectShow SDK已經根據各種不同的應用從CbaseFilter派生出了相應功能的子類。所要定制的Source Filter是一個實時源,同時需要在屬性頁中設置攝像頭的IP地址及其端口,以及幀速率,邊界大小等屬性。
選擇CSource類和CPersistStream類作為將要開發名為Finley’s Video Filter的Source Filter的父類。CSource類和CPersistStream類結構見圖2。

圖2 CSource類和CPersistStream類的結構示意
CSource類作為一般推模式Source Filter的父類,而CPersistStream類用于實現屬性頁。
Sample是一個封裝了一定大小數據內存的COM組建,它被用來傳輸Filter之間的數據。兩個連接的PIN共享同一個命名為Allocator的Sample分配器,用來創建、管理一個或多個Sample。在數據傳輸時,上一級Filter的輸出Pin調用ImemAllocator::GetBuffer函數,得到一個空閑Sample的數據內存地址,并放入數據。然后再將這個Sample傳送給下一級Filter的輸入Pin。數據從上一級Filter的輸出Pin傳送到下一級Filter的輸入Pin,并沒有進行數據的內存備份,而只是數據到達的通知。所以Pin的連接只是一個虛擬的邏輯連接,這樣做減少了所占用的資源并提高了運行效率。
Filter的數據傳輸分為推模式(push model)和拉模式(pull model)兩種形式。由于本系統用于船舶的視頻監視系統,所以采用的Source Filter屬于實時源(live source)。它能夠自己產生數據并用專門的線程將這些數據往下推送。數據從Capture Pin出來,調用數據流的下一個Filter的輸入Pin上的ImemInputPin::Receive函數,實現Source Filter到下一個Filter的傳送。同樣,下一個Filter也調用ImemInputPin::Receive進行數據的接收。
由于Filter都是COM組建,除了要重寫CreateInstance、NonDelegatingQueryInterface等函數外,還需要重寫CSource類和CPersistStream類中特定的虛函數。
CSource類的派生類要創建各個CSourceStream類實例。
GetMediaType:提供輸出Pin上首選媒體類型。
CheckMediaType:鏈接媒體類型的檢查。
DecideBufferSize:決定數據傳輸單元Sample的內存大小。
FillBuffer:在Sample中填充數據。
由于這4個函數是用于Filter之間的媒體協商的,應把它寫在CMonitorVideoPin中。
CPersistStream類主要是實現Filter設置界面的類,它的派生類要實現兩個重要的函數。
WriteToStream和ReadFromStream:用于寫入和讀取Filter設置的信息,如數據流的大小,IP地址,端口號,透明度,幀速率等,其中所有的屬性需要寫相應的實現函數。
Filter是一種組件,使用前必須注冊。首先需要為新Filter生成一個新的CLSID,同時要為屬性頁生成GUID。使用系統中的GuidGen.exe程序生成GUID,然后在命令行狀態下執行“regsvr32 Finley’s Video Filter的絕對路徑”即可。
本文硬件采用DS-2DF1-512海康威視攝像頭,采用千兆網與計算機相連。軟件采用VC和DirectShow庫編寫Source Filter,采用C++Builder編寫監視軟件。
Filter Graph是Filter的容器,是Filter鏈路的組合。首先在GraphEdit程序中加載所創建的Source Filter。Transform Filter和Rendering Filter分別采用DirectShow SDK提供的Color Space Converter和Video Mixing Renderer 9。把它們的輸出Pin與輸入Pin以此連接,見圖3。
根據實際需要對Filter的屬性進行設定。其中由于Color Space Converter不是CPersistStream的派生類,所以不能設置屬性。

圖3 Filter Graph結構示意
完成所有設置之后對Filter Graph進行保存。在主函數中調用API函數LoadGraphFile加載Filter Graph即可顯示實時視頻。
Filter有停止(Stopped)、暫停(Paused)和運行(Running)三種狀態。暫停可以認為是數據準備就緒狀態,也是停止與運行之間切換的中間狀態。所有Filter是通過IMediaFilter的接口方法來控制狀態轉換的。暫停和運行兩種狀態基本上是相同的,暫停只是阻塞了數據傳輸的線程。在本系統中因為Finley’s Video Filter是一個實時源,暫停過程中采集的數據已經失去了實時性,所以并不要求在暫停狀態下啟動數據傳輸。在這種情況下Video Mixing Renderer 9在暫停狀態下是接收不到任何Sample的。由于暫停和運行基本相同,而暫停又是運行與停止的中間狀態,下面著重討論停止與暫停兩個狀態的切換。
停止→暫停。從Video Mixing Renderer 9開始進行暫停狀態的轉換,同時Filter調用所有Pin的Active函數進行初始化,從后向前進入就緒狀態。當Finley’s Video Filter進入就緒狀態并啟動數據線程,開始發送Sample后,則狀態轉換完成。
暫停→停止。Video Mixing Renderer 9進入停止狀態時,調用所有Pin的Inactive函數,使上一級Filter調用IMemAllocator::GetBuffer脫離阻塞狀態,并終止所有Receive函數的等待,直到Finley’s Video Filter進入停止狀態。
其它的功能只需要設計新的Filter或采用DirectShow框架提供的相應的Filter,組成相應的Filter Graph即可實現。實現視頻流的文件存儲實現,只用在實時視頻播放Filter Graph中的Transform Filter后增加一個PIN,并把數據推入相應的File writer Filter中即可。實現視頻文件播放,在相應的Filter Graph中采用AVI/WAV File Source作為Source Filter即可。這些都是DirectShow SDK中提供的Filter,若需要其它特殊的功能則需要自己定制Filter。本系統自行定制了Finley’s File Source Filter用以視頻文件播放。
視頻監視系統滿足船舶行業日常安全管理和及時發現災情和隱患的需求,具有占用資源少,可移植性強等優點,為對數字視頻信息做進一步的處理,實現智能監控打下基礎。
[1] 韋 磊,張英俊,付瀟瀟,等.船舶視頻監控系統的研究[C]∥中國航海學會2006年度學術交流會優秀論文集,北京:中國航海學會,2007:184-186.
[2] 曹 輝,張均東,宋 威.視頻技術在船舶領域中的研究與應用[J].船海工程,2007,36(3):122-125.
[3] 黃振宇,王 敏,吳 濤.基于COM的Directshow Filter實現[J].微機發展,2004,14(5):113-116.
[4] 涂 超,葉家瑋.基于Direct Show的橋區船舶視頻采集系統開發[J].船海工程,2009,38(4):121-123.
[5] 陸其明.DirectShow開發指南[M].北京:清華大學出版社,2003.