现在的位置: 首页 > 综合 > 正文

CBasePin类、CBaseOutputPin类和CBaseInputPin类源代码解析(1)(转贴)

2013年12月11日 ⁄ 综合 ⁄ 共 5911字 ⁄ 字号 评论关闭
 

DirectShow 学习()CBasePin类、CBaseOutputPin类和CBaseInputPin类源代码解析

1.      IPin接口
IPin : public IUnknown
{
    public:
    //
连接两个Pin,主动连接InputPin
    virtual HRESULT STDMETHODCALLTYPE Connect(
            /* [in] */ IPin *pReceivePin,
            /* [in] */ const AM_MEDIA_TYPE *pmt) = 0;
    //
连接两个Pin,被动连接
    virtual HRESULT STDMETHODCALLTYPE ReceiveConnection(
            /* [in] */ IPin *pConnector,
            /* [in] */ const AM_MEDIA_TYPE *pmt) = 0;
    //
断开连接,只能在Stop状态下断开
    virtual HRESULT STDMETHODCALLTYPE Disconnect( void) = 0;
    //
得到连接的Pin的接口,成功返回连接的Pin被调用AddRef
    virtual HRESULT STDMETHODCALLTYPE ConnectedTo(
            /* [out] */ IPin **pPin) = 0;
    //
得到连接状态下的MediaType
    virtual HRESULT STDMETHODCALLTYPE ConnectionMediaType(
            /* [out] */ AM_MEDIA_TYPE *pmt) = 0;
    //
得到Pin的信息,填充PIN_INFO结构
    virtual HRESULT STDMETHODCALLTYPE QueryPinInfo(
            /* [out] */ PIN_INFO *pInfo) = 0;
    //
得到Pin的连接方向
    virtual HRESULT STDMETHODCALLTYPE QueryDirection(
            /* [out] */ PIN_DIRECTION *pPinDir) = 0;
    //
得到ID 其实是Pin中的name
    virtual HRESULT STDMETHODCALLTYPE QueryId(
            /* [out] */ LPWSTR *Id) = 0;
    // Determines whether the pin accepts a specified media type.
    virtual HRESULT STDMETHODCALLTYPE QueryAccept(
            /* [in] */ const AM_MEDIA_TYPE *pmt) = 0;
    // Enumerates the pin's preferred media types.
    virtual HRESULT STDMETHODCALLTYPE EnumMediaTypes(
            /* [out] */ IEnumMediaTypes **ppEnum) = 0;
    // Retrieves the pins that are connected internally to this pin (within the filter).
    virtual HRESULT STDMETHODCALLTYPE QueryInternalConnections(
            /* [out] */ IPin **apPin,
            /* [out][in] */ ULONG *nPin) = 0;
    // Notifies the pin that no additional data is expected
    virtual HRESULT STDMETHODCALLTYPE EndOfStream( void) = 0;
    // Begins / End a flush operation.
    virtual HRESULT STDMETHODCALLTYPE BeginFlush( void) = 0;
    virtual HRESULT STDMETHODCALLTYPE EndFlush( void) = 0;
    // Notifies the pin that media samples received after this call are grouped as a segment.
    virtual HRESULT STDMETHODCALLTYPE NewSegment(
            /* [in] */ REFERENCE_TIME tStart,
            /* [in] */ REFERENCE_TIME tStop,
            /* [in] */ double dRate) = 0;
};

2.      IQualityControl接口
IQualityControl : public IUnknown
{
public:
    // Notifies the recipient that a quality change is requested.
    virtual HRESULT STDMETHODCALLTYPE Notify(
        /* [in] */ IBaseFilter *pSelf,
        /* [in] */ Quality q) = 0;
    virtual HRESULT STDMETHODCALLTYPE SetSink(
        /* [in] */ IQualityControl *piqc) = 0;
};

3.      CBasePin[amfilter.h/amfilter.cpp]

o        派生自 CUnknown, IPin, IQualityControl
成员变量:
     WCHAR *          m_pName;          // This pin's name
     IPin             *m_Connected;               // Pin we have connected to
     PIN_DIRECTION    m_dir;                      // Direction of this pin
     CCritSec         *m_pLock;                   // Object we use for locking
    bool             m_bRunTimeError;            // Run time error generated
    bool             m_bCanReconnectWhenActive;  // OK to reconnect when active
    bool             m_bTryMyTypesFirst;         // When connecting enumerate
    CBaseFilter     *m_pFilter;                  // Filter we were created by
     IQualityControl *m_pQSink;                  // Target for Quality messages
     LONG             m_TypeVersion;              // Holds current type version
     CMediaType       m_mt;                       // Media type of connection
     CRefTime         m_tStart;                   // time from NewSegment call
     CRefTime         m_tStop;                    // time from NewSegment
    double           m_dRate;                    // rate from NewSegment
其中m_bRunTimeError默认为FALSEm_pQSink默认为NULLm_TypeVersion默认为1m_tStart为空,m_tStopMAX_TIMEm_bCanReconnectWhenActivem_bTryMyTypesFirst都为FALSEm_dRate1.0

o        Constructor:
     CBasePin(
         TCHAR *pObjectName,         // Object description
         CBaseFilter *pFilter,       // Owning filter who knows about pins
         CCritSec *pLock,            // Object who implements the lock
         HRESULT *phr,               // General OLE return code
         LPCWSTR pName,              // Pin name for us
         PIN_DIRECTION dir);         // Either PINDIR_INPUT or PINDIR_OUTPUT
m_pFilterpFilter初始化,m_pLockpLock初始化,m_dirdir初始化。

o        Pin之间的链接过程[详细Code讲解见陆其明《DirectShow开发指南》第二章的讲解],通过调用IPinConnect>AgreeMediaType(CBasePinProtected函数)->TryMediaTypes(CBasePinProtected函数)->AttempConnect(CBasePinProtected函数)
其中AttempConnect函数会首先调用CheckConnect(CBasePinVirtual函数),然后调用CheckMediaType(CBasePinVirtual函数),如果MediaType接受,则调用Receive Pin上的ReceiveConnection(IPin接口函数)函数,如果成功则调用CompleteConnection(CBasePinvirtual函数),否则调用BreakConnect(CBasePin上的virtual函数)

o        CBasePin中的新增加virtual函数和解释以及虚拟代码:
virtual LONG GetMediaTypeVersion();{return m_TypeVersion;}
// switch the pin to active (paused or running) mode not an error to call this if already active,
virtual HRESULT Active(void);{return NOERROR;}
// switch the pin to inactive state - may already be inactive
virtual HRESULT Inactive(void);{ return NOERROR; }
// Notify of Run() from filter,
virtual HRESULT Run(REFERENCE_TIME tStart);{ return NOERROR; }
// check if the pin can support this specific proposed type and forma
virtual HRESULT CheckMediaType(const CMediaType *) PURE;
必须Override
// set the connection to use this format (previously agreed)
virtual HRESULT SetMediaType(const CMediaType *);{ HRESULT hr = m_mt.Set(*pmt);}
// check that the connection is ok before verifying it can be overridden eg to check what interfaces will be supported.
virtual HRESULT CheckConnect(IPin *);
{CBasePin
中只检查了Pin的方向和当前方向是否一致}
// Set and release resources required for a connection
virtual HRESULT BreakConnect();{return NOERROR;}
virtual HRESULT CompleteConnect(IPin *pReceivePin); {return NOERROR;}
// returns the preferred formats for a pin
virtual HRESULT GetMediaType(int iPosition,CMediaType *pMediaType);
必须Override

o        CBasePin实现IPin的函数
QueryAccept -
直接调用CheckMediaType,并将结果返回
EnumMediaTypes -
通过辅助类CEnumMediaTypes实现MediaTypeEnum.
NewSegment
只是简单设置参数后直接返回NOERROR
Disconnect
调用函数 DisconnectInternal
Connect/ReceiveConnection
见上面条目。
其它的简单接口函数 ConnectionMediaTypeQueryPinInfoQueryDirection等略。

o        CBasePin中未实现IPin/IQualityControl的函数
直接设置为NOERROR的部分函数:
EndOfStream
直接设置为IMPL错误码的部分函数:
QueryInternalConnections
Notify[IQualityControl
接口]
完全没有实现的部分函数:
BeginFlush
EndFlush

 

抱歉!评论已关闭.