DirectShow基礎編程 源Filter CSource CSourceStream (轉)

 

 

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

DirectX SDK提供了一個C++的BaseClasses,是這些接口的實現。這些實現已經很成熟完善,所以咱們不須要從新開發一套類庫去實現DirctShow的接口,直接使用就能夠。數組

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

 

 

[cpp]  view plain copy print ?
 
  1. class CSource : public CBaseFilter  
  2. {  
  3. public:  
  4.     CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr);  
  5.     CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid);  
  6.     ~CSource();  
  7.     int       GetPinCount(void);  
  8.     CBasePin *GetPin(int n);  
  9.     CCritSec*   pStateLock(void) { return &m_cStateLock; }  
  10.     HRESULT     AddPin(CSourceStream *);  
  11.     HRESULT     RemovePin(CSourceStream *);  
  12.     STDMETHODIMP FindPin(LPCWSTR Id, IPin ** ppPin);  
  13.     int FindPinNumber(IPin *iPin);  
  14. protected:  
  15.     int             m_iPins;    
  16.     CSourceStream **m_paStreams;   
  17.     CCritSec m_cStateLock;  
  18. };  

 

CSource類從CBaseFilter類派生:ide

成員:函數

CSourceStream **m_paStreams; 源Filter能夠支持多個輸出pin,所以使用動態數組記錄pin指針。this

int  m_iPins;  pin的個數。spa

方法:.net

HRESULT     AddPin(CSourceStream *);添加pin。指針

HRESULT     RemovePin(CSourceStream *);移除pin。blog

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

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

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

實例化接口:

 

[cpp]  view plain copy print ?
 
  1. CUnknown * WINAPI CMySource::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)  
  2. {  
  3.     CUnknown *punk = new CMySource(lpunk, phr);  
  4.     return punk;  
  5. }  

 

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

實例化輸出pin:

 

[cpp]  view plain copy print ?
 
  1. CMySource::CMySource(LPUNKNOWN lpunk, HRESULT *phr)   
  2. : CSource(..., lpunk, CLSID_...)  
  3. {  
  4.   
  5.     CMyOutputPin* pOutPin = new CMyOutputPin(phr, this);  
  6.     if(FAILED(*phr))  
  7.     {  
  8.         RemovePin(pOutPin);  
  9.         pOutPin->Release();  
  10.     }  
  11. }  

 

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

 

 

 

[cpp]  view plain copy print ?
 
  1. class CSourceStream : public CAMThread, public CBaseOutputPin   
  2. {  
  3. public:  
  4.     CSourceStream(TCHAR *pObjectName,   HRESULT *phr,   CSource *pms,   LPCWSTR pName);  
  5.     virtual ~CSourceStream(void);   
  6. protected:  
  7.     CSource *m_pFilter;   
  8.     virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;  
  9. protected:  
  10.     virtual HRESULT CheckMediaType(const CMediaType *pMediaType);  
  11.     virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);   
  12. };  

 轉自: http://blog.csdn.net/bwmwm/article/details/5442259

輸出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這個例子。

相關文章
相關標籤/搜索