DirectShow基礎編程 源Filter CSource CSourceStream

來源:互聯網
上載者:User

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

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

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

 

class CSource : public CBaseFilter<br />{<br />public:<br />CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr);<br />CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid);<br />~CSource();<br />int GetPinCount(void);<br />CBasePin *GetPin(int n);<br />CCritSec*pStateLock(void) { return &m_cStateLock; }<br />HRESULT AddPin(CSourceStream *);<br />HRESULT RemovePin(CSourceStream *);<br />STDMETHODIMP FindPin(LPCWSTR Id, IPin ** ppPin);<br />int FindPinNumber(IPin *iPin);<br />protected:<br />int m_iPins;<br />CSourceStream **m_paStreams;<br />CCritSec m_cStateLock;<br />};

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。

執行個體化介面:

CUnknown * WINAPI CMySource::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)<br />{<br />CUnknown *punk = new CMySource(lpunk, phr);<br />return punk;<br />}

此介面類似這樣的固定格式。

執行個體化輸出pin:

CMySource::CMySource(LPUNKNOWN lpunk, HRESULT *phr)<br />: CSource(..., lpunk, CLSID_...)<br />{</p><p>CMyOutputPin* pOutPin = new CMyOutputPin(phr, this);<br />if(FAILED(*phr))<br />{<br />RemovePin(pOutPin);<br />pOutPin->Release();<br />}<br />}

在建構函式中執行個體化輸出pin,輸出pin的建構函式會自動把pin添加到CMySource中。

 

 

class CSourceStream : public CAMThread, public CBaseOutputPin<br />{<br />public:<br />CSourceStream(TCHAR *pObjectName,HRESULT *phr,CSource *pms,LPCWSTR pName);<br />virtual ~CSourceStream(void);<br />protected:<br />CSource *m_pFilter;<br />virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;<br />protected:<br />virtual HRESULT CheckMediaType(const CMediaType *pMediaType);<br />virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);<br />};

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.