對于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)