对于pin的连接过程,总结下.
1.
应用程序通过调用filter graph 管理器方法来连接filter.
应用程序调用IFilterGraph::ConnectDirect
IGraphBuilder::Connect来指定不同的filter直接连接,
也可用IGraphBuilder::RenderFile自动实现连接
应用程序可以通过IFilterGraph::AddFilter将filter 添加graph中,
当一个filter被添加到graph中时,filter图表管理器通过IBaseFilter::JoinFilterGraph来通知filter.
这点说明, 不是filter的直接连接函数相互链接,而是在以上内部调用实现的.
2. 考虑到以前描述
FilterA ---->FilterB
的连接检查媒体类型 逻辑基本就是这样:
循环FilterA的输出pin,再循环FilterB的输入Pin媒体类型是否和pmt媒体类型
匹配
for (j = 0 ; j<FilterB.PinIn.MediaTypeCount; j++)
{
if (FilterB.PinIn.MediaType[j] = pmt )
{
if(FilterA.PinIn.ReceiveConnection(FilterA.PinOut, FilterB.MediaType[i]) = OK)
return TRUE;
}
}
for (i= 0; i< FilterA.PinOut.MediaTypeCount; i++)
{
if (FilterA.PinOut.MediaType[i] 是否在FilterB.PinIn中是否支持)
if (FilterA.PinIn.ReceiveConnection(FilterA.PinOut, FilterA.MediaType[i]) = OK)
return TRUE;
}
在实现上,调用次序以下过程:
filterGraph首先调用FilterA.PinOut::Connect().
FilterA.IPinOut::Connect()
原型:IPin::Connect(IPin* pReceivePin, const AM_MEDIA_TYPE * pmt)
该Connect参数为
pReceivePin 为 FilterB的输入Pin,
pmt 是FilterA的当前媒体类型.
在内部调用(主要)
hr = AgreeMediaType(pReceivePin, pmt);
检查pReceivePin 有否pmt的媒体类型.
有,则自然ok
没有,失败,退出该函数.
则在AgreeMediaType做了以上逻辑循环.
IPin::AgreeMediaType函数处理如下:
1.判断pmt 是否是完全媒体类型,是则按全媒体类型模式出来
2.非完全媒体类型
IPin::EnumMediaTypes(IEnumMediaTypes** pEnum)
获取枚举指针(指向Pin中的媒体类型集合).
先枚举filterB的输入Pin的媒体类型的枚举集,
调用TryMediaTypes 函数去判断是否匹配.
还不匹配,取出FilterA的枚举类指针.再调用TryMediaTyes
IPin::TryMediaType()处理
原型:
HRESULT CBasePin::TryMediaTypes(IPin*pReceivePin, const CMediaType*pmt,
IEnumMediaType *pEnum)
在该函数处理:
for (pmt in 所有该枚举集中的枚举媒体类型 )
{
AttemptConnect(pReceivePin, pmt)
}
在AttemptConnection中调用
CBasePin::AttemptConnection(IPin* pReceivePin, const CMediaType*pmt)
检查FilterA 的CheckConnect(pReceivePin)
FilterA的PInOut::CheckMediaType(pmt)
ok,return
FilterA的PinOut::SetMediaType(pmt)
pReceivePin->ReceiveConnection(...) (filterB 的PinIn)
ok,return
FilterA的PinOut::CompleteConnect(pReceivePin)