DirectShow基礎編程 源Filter CSource CSourceStream

DirectShow是微軟定義的一套接口集合,由不同的接口組成,例如:IBaseFilter,IPin。這些接口之間的關係形成了DirectShow的架構。

DirectX SDK提供了一個C++的BaseClasses,是這些接口的實現。這些實現已經很成熟完善,因此我們不需要重新開發一套類庫去實現DirctShow的接口,直接使用就可以。

DirectShow編程就是Filter編程,根據功能實現不同的Filter。推模式的源Filter一般從CSource派生,在派生類中實現特殊的功能,而CSource類使用CSourceStream派生的pin。那麼,推模式的源Filter編寫就是實現這兩個類。

 

CSource類從CBaseFilter類派生:

成員:

CSourceStream **m_paStreams; 源Filter可以支持多個輸出pin,因此使用動態數組記錄pin指針。

int  m_iPins;  pin的個數。

方法:

HRESULT     AddPin(CSourceStream *);添加pin。

HRESULT     RemovePin(CSourceStream *);移除pin。

STDMETHODIMP FindPin(LPCWSTR Id, IPin ** ppPin);查找pin。

int       GetPinCount(void);獲取pin個數。

可見,CSource類就是對pin的管理。更多的功能,由CBaseFilter實現。實現自己的CSource類只需要做兩件事:提供實例化接口;實例化輸出pin。

實例化接口:

此接口類似這樣的固定格式。

實例化輸出pin:

在構造函數中實例化輸出pin,輸出pin的構造函數會自動把pin添加到CMySource中。

 

 

輸出pin從CBaseOutputPin派生,CSource類必須使用CSourceStream的派生類做輸出pin。

成員:

CSource *m_pFilter;記錄Filter的指針,通過構造函數賦值。

方法:

virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;填充數據,PURE被定義爲=0,CSourceStream是一個抽象類,不能實例化,派生類必須實現這個函數。函數的實現中需要做的就是像參數傳入的IMediaSample中填數據,這個數據會被傳到下游的Filter。

virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);這個函數雖然不是一個純虛函數,但是,我們必須重新現在它,來獲得自定義的媒體類型。

virtual HRESULT CheckMediaType(const CMediaType *pMediaType);連接的兩個pin之間匹配媒體類型,在此函數的實現中,可以把主類型子類型等等有必要比較的數據進行一遍比較,完全滿足則返回成功,否則返回失敗,匹配失敗,則連接失敗。因此,連接的過程實際上就是匹配媒體類型的過程,CheckMediaType最終是在CBasePin::Connect()中被使用。

virtual HRESULT DecideBufferSize(IMemAllocator * pAlloc,ALLOCATOR_PROPERTIES * ppropInputRequest) PURE;在CBaseOutputPin中聲明這個純虛函數,因此,派生類中必須實現,這個函數是在協商存儲空間的時候決定數據的大小。

 

通常情況下,一個源Filter只需要自己實現以上提到的內容,其他的都有固定的格式。固定格式可以參照SDK中ball這個例子。

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