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

4.      CBaseOutputPin [amfilter.h/amfilter.cpp]

o        CBaseOutputPin具体实现伪代码
派生自 CBasePin
变量部分(均初始化为NULL):
IMemAllocator *m_pAllocator; // Memory allocator
IMemInputPin *m_pInputPin;  // interface on the downstreaminput pin

o        新增加的virtual函数:
// negotiate the allocator and its buffer size/count and other properties
// Calls
DecideBufferSize to set properties
virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc);
{
// 调用 pPin->GetAllocatorRequirements. 得到Input Pin的Prop.
// 调用 pPin->GetAllocator判断pPin是否以及存在Allocator,
// 否则自己创建并初始化(InitAlloc)并调用 DecideBufferSize 来得到需要的大小
// 调用 pPin->NotifyAllocator让Input Pin得到更新的Allocator
}
// override this to set the buffer size and count. Return an error
virtual HRESULT DecideBufferSize(
     IMemAllocator * pAlloc,
     ALLOCATOR_PROPERTIES * ppropInputRequest
) PURE;
// returns an empty sample buffer from the allocator
virtual HRESULT GetDeliveryBuffer(IMediaSample ** ppSample,
                                   REFERENCE_TIME * pStartTime,
                                   REFERENCE_TIME * pEndTime,
                                   DWORD dwFlags);
{调用 m_pAllocator->GetBuffer(…) }
// deliver a filled-in sample to the connected input pin
// note - you need to release it after calling this. The receiving
virtual HRESULT Deliver(IMediaSample *);{ m_pInputPin->Receive(pSample); }
// override this to control the connection
virtual HRESULT InitAllocator(IMemAllocator **ppAlloc);{ CreateMemoryAllocator(ppAlloc); }
// called from elsewhere in our filter to pass EOS downstream to our connected input pin
virtual HRESULT DeliverEndOfStream(void);{ m_Connected->EndOfStream(); }
virtual HRESULT DeliverBeginFlush(void);{ m_Connected->BeginFlush(); }
virtual HRESULT DeliverEndFlush(void);{ m_Connected->EndFlush(); }
virtual HRESULT DeliverNewSegment(
                     REFERENCE_TIME tStart,
                     REFERENCE_TIME tStop,
                    double dRate);{ m_Connected->NewSegment(…);}

o        继承的virtual函数或者IPin接口函数:
// Complete connection
virtual HRESULT CompleteConnect(IPin *pReceivePin); { DecideAllocator() }
// Check connection
HRESULT CheckConnect(IPin *pPin);
{增加检查输入Pin是否支持IMemInputPin接口,m_pInputPin在这里赋值}
// Break connection
HRESULT BreakConnect();
{
// 调用m_pAllocator->Decommit()释放m_pAllocator并置为空,
// 释放m_pInputPin并置为空
}
HRESULT Active(void);{ m_pAllocator->Commit(); }
HRESULT Inactive(void); { m_pAllocator->Decommit();}
以下三个函数直接返回E_UNEXPECTED
STDMETHODIMP EndOfStream(void);
STDMETHODIMP BeginFlush(void);
STDMETHODIMP EndFlush(void);

5.      IMemInputPin接口函数:
IMemInputPin : public IUnknown
{

     // Retrieves the memory allocator proposed by this pin.
     virtual HRESULT STDMETHODCALLTYPE GetAllocator(
         /* [out] */ IMemAllocator **ppAllocator) = 0;
     // Specifies an allocator for the connection.
     
virtual HRESULT STDMETHODCALLTYPE NotifyAllocator(
         /* [in] */ IMemAllocator *pAllocator,
         /* [in] */ BOOL bReadOnly) = 0;
     // Retrieves allocator properties that are requested by the input pin.
     
virtual HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(
         /* [out] */ ALLOCATOR_PROPERTIES *pProps) = 0;
     // Receives the next media sample in the stream.
     
virtual HRESULT STDMETHODCALLTYPE Receive(
         /* [in] */ IMediaSample *pSample) = 0;
     // Receives multiple samples in the stream.
     
virtual HRESULT STDMETHODCALLTYPE ReceiveMultiple(
         /* [size_is][in] */ IMediaSample **pSamples,
         /* [in] */ long nSamples,
         /* [out] */ long *nSamplesProcessed) = 0;
     // Determines whether calls to the Recive method might block.
     
virtual HRESULT STDMETHODCALLTYPE ReceiveCanBlock( void) = 0;
}

6.      CBaseInputPin[amfilter.h/amfilter.cpp]

o        CBaseInputPin具体实现伪代码:
派生自 CBasePin, IMemInputPin
变量部分:
IMemAllocator *m_pAllocator;    // Default memory allocator
// Allocator is read only or not

BYTE m_bReadOnly;
// in flushing state (between BeginFlush and EndFlush)
// if TRUE, all Receives are returned with S_FALSE

BYTE m_bFlushing;
// Sample properties - initalized in Receive
AM_SAMPLE2_PROPERTIES m_SampleProps;
INonDelegationUnknown的接口函数:
// 重写该函数是为了支持IMemInputPin接口
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
具体实现函数:
HRESULT PassNotify(Quality& q);
{
// 如果m_pQSink不为空,直接调用m_pQSink->Notify(…)
// 否则查询Connect Pin上的IQualityControl借口,对其调用Notify(…)
}

o        新增的virtual函数
//   Override this for checking whether it's OK to process samples
//   Also call this from EndOfStream.
virtual HRESULT CheckStreaming();
{分别判断IsStopped、m_bFlushing和m_bRunTimeError }

o        IMemInputPin接口函数:
// return the allocator interface that this input pin
// would like the output pin to use
STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator);
{
// 如果m_pAllocator为空,则CreateMemoryAllocator
// 调用m_pAllocator->AddRef,返回m_pAllocator
}
// tell the input pin which allocator the output pin is actually going to use.
STDMETHODIMP NotifyAllocator(
                 IMemAllocator * pAllocator,
                 BOOL bReadOnly);
{
// 释放当前m_pAllocator,设置m_pAllocator = pAllocator
// 调用m_pAllocator->AddRef
}
// do something with this media sample
STDMETHODIMP Receive(IMediaSample *pSample);
{
// 首先调用CheckStreaming
// 得出pSample的属性,即填充成员m_SampleProps
// 如果Sample属性未发生变化(!(m_SampleProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED))
// 则直接返回NOERROR,否则调用CheckMediaType检查是否接受新的MediaType,如果接受
// 返回NOERROR,否则调用EndOfStream,设置RuntimeError,并通知Filter
// m_pFilter->NotifyEvent(EC_ERRORABORT,VFW_E_TYPE_NOT_ACCEPTED,0);
}
// do something with these media samples
STDMETHODIMP ReceiveMultiple (
     IMediaSample **pSamples,
    long nSamples,
    long *nSamplesProcessed);
{
// 对每个Sample分别调用Receive函数。
}
// See if Receive() blocks
STDMETHODIMP ReceiveCanBlock();
{
// 如果当前Filter上没有Output Pin,则返回S_OK
// 否则遍历当前Filter上每个Output Pin,得出它们的Connected Input Pin,判断这些
// Connected Input Pin是否支持Block,只要有一个支持,则为S_OK
// 以上条件全不满足时,返回S_FALSE
}
// default implementation returns E_NOTIMPL. Override if you have
// specific alignment or prefix needs, but could use an upstream allocator
STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps);{E_IMPL}

o        继承的virtual函数实现
STDMETHODIMP BeginFlush(void);
{仅仅设置m_bFlushing为TRUE.}
STDMETHODIMP EndFlush(void);
{仅仅设置m_bFlushing为FALSE,同时清除m_bRuntimeError。}
HRESULT BreakConnect();
{
// 如果m_pAllocator非空,调用m_pAllocator->Decommit()
// 释放m_pAllocator->Release并置为空
}
virtual HRESULT Inactive(void);
{
// 清理m_bRunTimeError和m_bFlushing,返回m_pAllocator->Decommit().
}
STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
{这是IQualityControl的接口函数,CBaseInputPin只是简单报错DbgBreak说明未实现}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值