王 輝,陳浩明,王小英
(常熟理工學院 計算機科學與工程學院,江蘇 常熟 215500)
DirectShow是微軟公司在ActiveMovie和Video for Windows的基礎上推出的新一代基于COM(Component Object Model)的流媒體處理的開發包[1].它采用流水線的工作思想,可以實時處理并輸出采集到的數據流,具有很強的時效性和靈活性.DirectShow屏蔽了硬件設備的差異性,降低了流媒體處理軟件的開發難度,支持多種媒體數據類型的解碼播放、格式轉化,同時還具有VFW(Video for Windows)視頻采集方式所不支持的多路音視頻數據同時采集的功能,可以輕松地應用于視頻監視系統、視頻會議、視頻點播等系統的開發[2,3].
目前隨著嵌入式系統的普及,DirectShow被成功地移植到了Windows CE嵌入式系統之中[4],為Windows CE系統中的多媒體應用的開發提供了有力的支持.通過DirectShow技術,可以基于Windows CE嵌入式系統高效的開發OCR(Optical Character Recognition)(光學字符識別)產品,網絡視頻監視產品,網絡視頻會議播放產品等一些具有廣闊市場前景的流媒體應用產品.
DirectShow是一個開放性的應用架構,如圖1所示.應用程序在使用DirectShow時將按照一定的意圖建立起相應的Filter Graph,通過Filter Graph Manager來控制整個數據處理過程.DirectShow在Filter Graph運行的時候接收各種事件,通過消息的方式發送到應用程序,實現應用程序與DirectShow系統之間的交互.
DirectShow中有三種Filter,分別是Source Filter,Transform Filter和Rendering Filter.Source Filters主要負責取得數據,數據源可以是文件、因特網、或者計算機里的采集卡、數字攝像機等,然后將數據向下傳輸;Transform Filers主要負責數據的格式轉換、傳輸;Rendering Filters主要負責數據的最終去向,可以將數據傳送至聲卡、顯卡進行多媒體的演示,也可以輸出到文件進行存儲.每個Filter都有其自己的連接Pin.Filter通過輸入和輸出Pin進行不同Filter之間的連接.
DirectShow采用了COM標準,在Direct-Show中提供了IGraphBuilder、IMediaControl、IVideoWindow等重要接口來完成視頻流的采集與控制功能.使用DirectShow進行攝像頭的視頻流捕獲時,首先需構建一個ICaptureGraphBuilder2和IGraphBuilder的COM對象,然后對攝像頭驅動進行枚舉,并將視頻捕獲濾鏡與攝像頭驅動建立關聯,最終通過IGraphBuilder的對象查找IMediaControl接口和IVideoWindows接口實現預覽窗體的設置和流媒體的基本控制.

圖1 DirectShow系統框架
在Windows CE5.0以上的版本中都提供了可以直接調用攝像頭的API函數,但是這些函數功能都過于簡單,為此Microsoft公司又將DirectShow移植到Windows CE5.0以上的系統中,針對嵌入式設備的CPU的處理能力較弱以及嵌入式設備的內存容量較小的特點,Microsoft公司在移植DirectShow時也進行了必要裁剪,而這也導致了在Windows CE上進行DirectShow應用的開發相比于在PC機上的開發要有所不同.
本軟件的開發使用Visual Studio 2005開發工具中的智能設備開發環境,語言選擇了c++,因為c++可以自由地申請和釋放內存,以節約嵌入式系統中的有限內存資源.在開發Windows CE應用程序之前,首先需要安裝Windows CE的SDK,該開發包提供了DirectShow應用程序開發所需的庫函數.
為了在工程里面能夠正常地使用DirectShow,首先需要在工程中添加“dshow.h”頭文件以及aygshell.lib和strmiids.lib兩個靜態庫.由于DirectShow是基于COM開發,因此為了方便接口的調用和釋放,可以使用智能指針CComptr<>,因此也需要添加atlbase.h這個頭文件.
DirectShow在Windows CE系統上驅動攝像頭,采集圖像并保存的流程如圖2所示.
本文在 Windows CE系統中通過DirectShow技術實現了視頻捕獲的應用軟件,主要包括視頻流采集與預覽、視頻流和圖片保存、視頻流格式設置以及預覽窗體創建四個模塊.
該模塊為整個軟件的核心部分,其流程圖如圖3所示.在該流程中,查找攝像頭的驅動并與視頻捕獲濾鏡建立關聯的方法不同于PC機上方式,因為Windows CE中的攝像頭數目有限,不需要特意地去枚舉視頻捕捉設備,Windows CE的SDK中提供了FindFirstDevice函數,可以方便地查找到攝像頭設備.
通過FindFirstDevice進行查找設備驅動時需要使用Windows CE中攝像頭驅動的GUID,其GUID為{0xCB998A05,0x122C,0x4166,0x84,0x6A,0x93,0x3E,0x4D,0x7E,0x3C,0x86}.其實現代碼如下:

圖2 DirectShow在Windows CE上的圖像采集

在實現圖片或視頻保存時,DirectShow提供了設置視頻或圖片存儲格式的功能,但是這些功能受到硬件條件的制約,并非每款設備上都能實現對視頻或圖片格式的設置.
對圖片進行保存的核心實現代碼如下:


圖3 視頻流捕獲模塊流程圖
通過DirectShow技術可以比較簡單地設置視頻流的像素、采集頻率以及圖像的位數,不過這些參數的設置也需要硬件的支持才可以實現.視頻格式的設置主要由IAMStreamConfig接口提供,該接口由ICaptureGraph-Builder2的COM對象獲得,在Windows CE中可以使用 AM_MEDIA_TYPE和VIDEOINFOHEADER結構體來保存原始視頻流格式以及設置后的視頻流的格式.
DirectShow在進行預覽攝像頭采集的視頻流之前需要先設置預覽窗體,該窗體的接口通過濾鏡管理器進行查詢得出.控制視頻窗體的接口為IVedioWindow,通過該接口可以設置視頻窗體的風格,大小和所在窗體的位置.視頻流能夠正常運行還需要IGraphBuild的COM對象提供IMediaControl接口來進行控制,只有視頻流進行了正常采集的時候,預覽窗體才會進行視頻流的實時顯示.

圖4 DirectShow技術實現的系統

圖5 設置顯示窗體的大小
圖4和圖5分別是用DirectShow技術和系統自帶的API函數實現的圖像采集系統.采用DirectShow技術實現的系統其靈活性遠遠超過了采用系統自帶的API函數實現的系統.該軟件可以設置圖像的分辨率、視頻預覽窗體的大小、視頻的旋轉、保存視頻流或從視頻流中捕獲的圖片,實現了視頻采集應用的基本功能.同時,使用DirectShow自帶的濾鏡或者用戶自定義的濾鏡可以實現視頻流的實時處理,還可以開發更為高級的應用功能,而使用Windows CE系統中自帶的一些API時,只能調用系統自帶的拍照程序,用戶無法對其添加其他功能,也不能對實時的視頻流進行處理,無法開發一些具有實際價值的應用.
除此之外,因為DirectShow只涉及到視頻流的采集與處理,因此軟件的界面可以由開發人員自由設計,而調用Windows CE自帶的API函數時,開發人員無法對其軟件界面進行修改.在進行單獨的拍照測試時,使用DirectShow開發的視頻采集軟件的速度也要優于直接調用系統API函數開發的系統.
本文研究了DirectShow技術的框架及關鍵技術,并在Windows CE系統中實現了視頻流的圖像采集、預覽、處理、保存等功能,為今后在Windows CE嵌入式系統中開發視頻監視系統、OCR系統,以及將Windows CE系統應用到攝像機、照相機等設備中提供了初步的技術驗證.
[1]陸其明.DirectShow開發指南[M].北京:清華大學出版社,2009.
[2]唐蕓,杜江紅,陳繼華.基于COM技術的DirectShow視頻采集的研究[J].三峽大學學報(自然科學版),2003(6).
[3]黃振宇,王敏,吳濤.基于COM的Directshow Filter實現[J].微機發展,2004(5).
[4]邱小平.WindowsCE 6.0開發經典[M].北京:電子工業出版社,2009.