編寫DirectShow Filters—概述

seeker

(一) 介紹DirectShow Filter開發
本章提供開發一個自定義DirectShow filter的簡單框架描述,也提供了鏈接到更詳細討論這些任務的主題。在閱讀本章之前,閱讀在About DirectShow主題,它描述了全面的DirectShow構架。
1. DirectShow基類庫
Directshow sdk包括了編寫filters的一組C++類。雖然它們不是必需的,但推薦使用這些類來編寫一個新的filter。爲了使用這些基類,需要把它們編譯成靜態庫並鏈接.lib文件到自己的項目中,如building DirectShow Filters中的描述。
基礎類庫定義了filters的一個根類,CBaseFilter類。幾個其它的類繼承自CBaseFitler,並且指定於其它特定類型的filters。如,CTransformFilter類設計爲transform類。爲了建立一個新filter,實現繼承自filters類中的一個的類。如,你的類聲明可能如下表示:
class CMyFilter : public CTransformFilter
{
private:
 // declare variables and methods that are specific to your filter
public:
//override various methods in CTransformFilter
};
2. 建立PINs
filter必須建立一個或多個pin。pin的數目可能在設計時間固定或者根據需要創建。pin一般繼承自CBasePin類或者從繼承自CBasePin的類來繼承,如CBaseInputPin。filter的pin應該聲明爲filter類的成員變量。一些filter類已經定義了pin,但如果你的filter繼承自CBaseFilter,你必須在你的繼承類中聲明這些pin。
3. 協商pin連接
當filter graph manager試圖去連接兩個filters,pins必須在各種事情上達成一致。如果不能,連接試圖失敗。一般,PIN協商如下列:
1) transport:transport是filters用來從output pin移動media sample到input pin的機制。例如,它們可以使用IMemInputPin接口(推模型)或者IAsyncReader接口(拉模型)。
2) Media type : 大多數pins使用media type來描述它們傳遞的數據格式
3) Allocator : allocator是建立緩衝區來保存數據的對象。pins必須一致哪個PIN來提供allocator。必須在buffers的尺寸上,buffers建立的數目上和其它buffer屬性上一致。
基類實現了這些協商的Framework,你必須通過重載在基類中的各種方法來完成細節。這些重載的方法的設置依賴於類和自定義filter的功能性。
4. 處理和傳遞數據
大多數filters的主要功能是處理和傳遞數據。如何傳遞根據filter的類型
1) push source有一個工作線程,它持續的用數據填充sample並傳遞到downstream。
2) pull source等待它臨近的downstream來請求一個Sample。它通過寫數據到一個Sample並傳遞這個sample到downstream filter來響應。這個 downstream filter建立傳遞數據流動的線程。
3) transform filter通過它臨近upstream filter傳遞samples。當它接收一個sample,處理數據並傳遞到downstream
4) renderer filter從upstream接收sample,並依據時間戳安排它們rendering。
其它流任務包括從graph中flushing數據,處理流的結束,響應seek請求,
5. 支持COM
DirectShow filter都是COM對象,一般在DLL中打包,基類庫實現了一個支持COM的框架。

(二) 生成DirectShow Filters
DirectShow基類推薦用來實現DirectShow filter。爲了生成基類,執行下列步驟:
1) 生成基類庫, 位於SDK根目錄下的Samples/Multimedia/DirectShow/BaseClasses,有兩個庫版本:retail版(strmbased.lib) 和debug版(strmbasd.lib)。
2) 包括stream.h頭文件
3) 使用__stdcall調用轉換(c/c++->高級)
4) 使用多線程的C run-time庫(debug/retail)(c/c++->代碼生成)
5) 包括一個定義文件(.def)暴露DLL函數,如下列範例:假定輸出文件名爲MyFilter.dll
LIBRARY MYFILTER.DLL
EXPORTS
    DllMain             PRIVATE
    DllGetClassObject   PRIVATE
    DllCanUnloadNow     PRIVATE
    DllRegisterServer   PRIVATE
    DllUnregisterServer PRIVATE
6) 鏈接到下列庫文件
Debug Build :Strmbasd.lib, Msvcrtd.lib, Winmm.lib
Retail Build :Strmbase.lib, Msvcrt.lib, Winmm.lib
7) 在linker 設置選擇"ignore default libraries"。
8) 在源代碼中聲明DLL入口點,如下:
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
    return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章