2011年12月13日 星期二

如何使用C#來實作簡單的Directshow影像擷取軟體

女神異聞錄3  高國華  基測百分百

一、 程式說明:


使用Directshow提供的Filter來製作簡單的影像擷取軟體,主要的功能是顯示及錄製由擷取設備所傳送的


影像資料,而該軟體錄製的影像格式隻支援Windows影片格式且除了影片播放外還提供圖片擷取儲存的功能。


(DirectShow SDK下載)


 


二、相關的Filter使用說明:


1. Filter Graph Manager (CLSID_FilterGraph) - 


 Direct Show的中央單元,主要是用來管理Filter之間的控制同步化、事件通知…等各種的


Filter Graph控制,操作方式主要是使用下列的介面來完成:


1-1、IMediaControl  (IID_IMediaControl) -  


控制通過Filter Graph中資料流處理的方式,例如:running、pausing, and stopping...等。


1-2、IVideoWindow(IID_IVideoWindow) -


設定Filter Graph內的Video Window的相關屬性。


1-4、IMediaEventEx (IID_IMediaEventEx) - 


接收Filter Graph中的事件通知及overriding(覆寫)Filter Graph中事件的預設控制。




2. Capture Graph Builder 2 (CLSID_CaptureGraphBuilder2) - 


由Directshow提供的Helper Object 使應用程式可以容易的建立及控制Capture Graph,但由於


CGB本身不包含 VMR9、VMR7、EVR Filters,因此必須將FGM的IGB作為CGB處理影像及音聲資訊的Filter。


 


3. Sample Grabber (CLSID_SampleGrabber) -


這是轉換用的Filter,從經過該Filter內的資料流中擷取多媒體樣本,在此的功能為取得的視訊資料


                並存成圖片。


1-1、ISampleGrabber (IID_ISampleGrabber) -


                        設定Sample Grabber接收多媒體的類型及處理資料的方式。


 


4. Null Renderer Filter  (CLSID_NullRenderer) - 

吸血鬼了沒

這個渲染器主是將接收的資料直接丟棄,不做任何後續的處理。主要是對於某些Filter


                必須要有一個downstream 的連接對象而又沒有適當的需求時使用。


 


三、使用GraphEdit來說明程式的執行流程:


      3-1. 基本設定的程式流程:


          (1) 建立Filter Graph Manage 並取得上述的介面來進行後續的操作。


          (2) 建立Capture Graph Builder並使用SetFiltergraph函式來指定ICB作為ICGB2的操作對象。


          (3) 設定IMediaEventEx介面的SetNotifyWindow來取得ICB內的相關事件訊息。


          (4) 使用下列二個函式來取得連接設備的IBaseFilter:


                CreateBindCtx 一 回傳一個IBindCtx (a bin context object)用來儲存Moniker-binding的作業。


                MkParseDisplayName 一


                      使用設備名稱進行檢索並回傳一個Moniker介面並使用該回傳的Moniker的BindToObject來取得


                ICB所需的溝通介面IBaseFilter。


          (5) 使用IGB的AddFilter函式,將取的設定的Filter加入IGB。


          (6) 使用ICGB2的ReanderStream函式來連接Device Filter的聲音的預覽輸出。       


          (7) 使用ICGB2的ReanderStream函式來連接Device Filter的影像的預覽輸出。       


          (8) 使用IVideoWindow介面來設定Video Window的父視窗、樣式及位置…等參數。


 


      3-2. 使用Sample Grabber來儲存圖片的程式流程:


          (1) 建立Sample Grabber Filter並使用IGB的AddFilter函式將該Filter加入其中。


          (2) 建立Null Renderer Filter並使用IGB的AddFilter函式將該Filter也加入其中。


          (3) 使用ICGB2的RenderStream將Device Filter和Sample Grab Filter和NullReader連接起來。(如下圖所示)


          (4) 取得Sample Grabber Filter的控制介面ISampleGrabber來對所建立的Sample Grabber Filter進行相關參數設定。              


          capture_videobysamplegrab.jpg  


 


      3-3. 使用無壓縮的AVI格式來錄製影片檔:


          (1) 使用ICGB2的SetOutputFilterName的函式並選擇使用CLSID_MEDIASUBTYPE_Avi作為輸出的影像檔案格式並取得


                Multiplexer的IBase Filter及File Writer的IFileSkinFilter。


          (2) 使用ICGB2的RenderStream函式將Device Filter中的聲音的擷取輸出至Multiplexer的IBase Filter。


               (依設備功能而定)


          (3) 使用ICGB2的RenderStream函式將Device Filter中的影像的擷取輸出至Multiplexer的IBase Filter。


            capture_recordbyavi.jpg  


 


         3-4. 使用有壓縮的ASF格式來錄製影片檔:


          (1) 使用ICGB2的SetOutputFilterName函式並選擇使用CLSID_MEDIASUBTYPE_Asf作為輸出的影像檔案格式並取得


                Multiplexer的IBase Filter及File Writer的IFileSkinFilter。


          (2) 取得Mutiplexer提供的IConfigAsfWriter介面並設定為系統預設的值。


          (3) 使用IConfigureAsWriter的GetCurrentProfile函式來取的IWMProfile控制介面。


          (4) 使用ICGB2的FindInterface函式取得Device Fliter的IAMStreamConfig介面來取得串流的多媒體格式。


          (5) 依據串流的多媒體格式來重新設定IWMProfile的多媒體儲存格式。


          (6) 使用IWMProfile介面的ReconfigStream函式來儲存修改後的設定值。


          (4) 使用ICGB2的RenderStream函式將Device Filter中的聲音的擷取輸出至Multiplexer的IBase Filter。


               (依設備功能而定)


          (5) 使用ICGB2的RenderStream函式將Device Filter中的影像的擷取輸出至Multiplexer的IBase Filter。


 


           capture_recordbyasf.jpg  


 


 


四、程式執行畫面:


       4-1. 圖片擷取模式 一


       capture-demo1.jpg  


       4-2. 錄影模式 一


       capture-demo2.jpg


      4-3. 關閉預覽錄影模式 一


      capture-no review.jpg  


Download: DSCapture.rar (Source Code)         DSCapture.exe(Binary code)



沒有留言:

張貼留言