DirectShow基础编程 源Filter CSource CSourceStream


DirectShow是微软定义的一套接口集合,由不同的接口组成,例 如:IBaseFilter,IPin。这些接口之间的关系形成了DirectShow的架构。

DirectX SDK提供了一个C++的BaseClasses,是这些接口的实现。这些实现已经很成熟完善,因此我们不需要重新开发一套类库去实现DirctShow 的接口,直接使用就可以。

DirectShow编程就是Filter编程,根据功能实现不同的Filter。推模式的源Filter一般从CSource派生,在派生类中实 现特殊的功能,而CSource类使用CSourceStream派生的pin。那么,推模式的源Filter编写就是实现这两个类。

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

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。

实例化接口:

  1. CUnknown * WINAPI CMySource::CreateInstance(LPUNKNOWN lpunk,  HRESULT  *phr)  
  2. {  
  3.     CUnknown *punk = new  CMySource(lpunk, phr);  
  4.     return  punk;  
  5. }  
  1. CUnknown * WINAPI   
  2. CMySource::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)  
  3. {  
  4.     CUnknown *punk = new CMySource(lpunk, phr);  
  5.     return punk;  
  6. }  

此接口类似这样的固定格式。

实例化输出pin:

  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. }  
  1. CMySource::CMySource(LPUNKNOWN  
  2.  lpunk, HRESULT *phr)   
  3. : CSource(..., lpunk, CLSID_...)  
  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中。

  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. };  
  1. class CSourceStream :  
  2.  public CAMThread, public CBaseOutputPin   
  3. {  
  4. public:  
  5.     CSourceStream(TCHAR *pObjectName,   HRESULT *phr,   CSource *pms,   LPCWSTR   
  6. pName);  
  7.     virtual ~CSourceStream(void);   
  8. protected:  
  9.     CSource *m_pFilter;   
  10.     virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;  
  11. protected:  
  12.     virtual HRESULT CheckMediaType(const CMediaType *pMediaType);  
  13.     virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);   
  14. };  

输出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这个例子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值