zoukankan      html  css  js  c++  java
  • 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. };  

    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. }  

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

    实例化输出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. }  

    在构造函数中实例化输出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. };  

     转自: 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这个例子。

  • 相关阅读:
    iOS开发UI篇—UITabBarController简单介绍
    iOS开发UI篇—ios应用数据存储方式(归档)
    iOS开发UI篇—ios应用数据存储方式(偏好设置)
    iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
    iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
    iOS开发UI篇—控制器的View的创建
    WordPress显示备案号
    jQuery插件之Wookmark瀑布流
    Nodejs电影建站开发实例(下)
    Nodejs电影建站开发实例(上)
  • 原文地址:https://www.cnblogs.com/signal/p/4094108.html
Copyright © 2011-2022 走看看