DirectShow2
STDMETHODIMP CBasePin::Connect(IPin *pReceivePin,const AM_MEDIA_TYPE *pmt/*optinal media type*/)
{
CheckPointer(pReceivePin,E_POINTER);
ValidateReadPtr(pReceivePin,sizeof(IPin));
CAutoLock cObjectLock(m_pLock);
DisplayPinInfo(pReceivePin);
\檢查該P(yáng)in是否已連接
if(m_Connected)
{
DbgLog((LOG_TRACE,CONNECT_TRACE_LEVEL,TEXT("Already connected")));
return VFW_E_ALREADY_CONNECTED;
}
\一般Filter只能在停止?fàn)顟B(tài)下進(jìn)行連接
if(!IsStopped()&&!m_bCanReconnectWhenActive)
{
return VFW_E_NOT_STOPPED;
}
\開始媒體類型的檢查過程,找出一種連接雙方都支持的媒體類型
const CMediaType *ptype=(CMediaType *)pmt;
HRESULT hr=AgreeMediaType(pReceivePin,ptype);
if(FAILED(hr))
{
DbgLog((LOG_TRACE,CONNECT_TRACE_LEVEL,TEXT("Failed to agree type")));
EXECUTE_ASSERT(SUCCEEDED(BreakConnect()));
return hr;
}
DbgLog((LOG_TRACE,CONNECT_TRACE_LEVEL,TEXT("Connection succeeded")));
return NOERROR;
}
HRESULT CBasePin::AgreeMediaType(IPin *pReceivePin,const CMediaType *pmt)
{
ASSERT(pReceivePin);
IEnumMediaType *pEnumMediaTypes=NULL;
\判斷pmt是不是一個完全指定的媒體類型
if((pmt!=NULL)&&(!pmt->IsPartiallySpecified()))
{
\用這個完全指定的媒體類型進(jìn)行試連接,如果試連接失敗,不再作其他嘗試
return AttemptConnection(pReceivePin,pmt);
}
HRESULT hrFailure=VFW_E_NO_ACCEPTABLE_TYPES;
\進(jìn)行Pin上支持的媒體類型枚舉,開始媒體類型的“協(xié)商”過程
for(int i=0;i<2;i++)
{
HRESULT hr;
if(i==(int)m_bTryMyTypesFirst)
{
hr=pReceivePin->EnumMediaTypes(&pEnumMediaTypes);
}
else
{
hr=EnumMediaTypes(&pEnumMediaTypes);
}
if(SUCCEEDED(hr))
{
ASSERT(pEnumMediaTypes);
hr=TryMediaTypes(pReceivePin,pmt,pEnumMediaTypes);
pEnumMediaTypes->Release();
if(SUCCEEDED(hr))
{
return NOERROR;
}
else
{
if((hr!=E_FAIL)&&(hr!=E_INVALIDARG)&&(hr!=VFW_E_TYPE_NOT_ACCEPTED))
{
hrFailure=hr;
}
}
}
}
return hrFailure;
}
HRESULT CBasePin::TryMediaTypes(IPin *pReceivePin,const CMediaType *pmt,IEnumMediaType *pEnum)
{
\復(fù)位枚舉器內(nèi)部狀態(tài)
HRESULT hr=pEnum->Reset();
if(FAILED(hr))
{
return hr;
}
CMediaType *pMediaType=NULL;
ULONG ulMediaCount=0;
HRESULT hrFailure=S_OK;
for(;;)
{
hr=pEnum->Next(1,(AM_MEDIA_TYPE **)&pMediaType,&ulMediaCount);
if(hr!=S_OK)
{
if(S_OK==hrFailure)
{
hrFailure=VFW_E_NO_ACCEPTABLE_TYPES;
}
return hrFailure;
}
ASSERT(ulMediaCount==1);
ASSERT(pMediaType);
\檢查當(dāng)前枚舉得到的媒體類型是否與不完全指定的媒體類型參數(shù)匹配
if((pmt==NULL)||pMediaType->MatchesPartial(pmt))
{
\進(jìn)行試連接
hr=AttemptConnection(pReceivePin,pMediaType);
if(FAILED(hr)&&SUCCEEDED(hrFailure)&&(hr!=E_FAIL)&&(hr!=E_INVALIDARG)&&(hr!=VFW_E_TYPE_NOT_ACCEPTED))
{
hrFailure=hr;
}
}
else
{
hr=VFW_E_NO_ACCEPTABLE_TYPES;
}
DeleteMediaType(pMediaType);
if(S_OK==hr)
{
return hr;
}
}
}
HRESULT CBasePin::AttemptConnection(IPin * pReceivePin,const CMediaType *pmt)
{
//獲取Filter對象上的操作權(quán)
ASSERT(CritCheckIn(m_pLock));
HRESULT hr=CheckConnect(pReceivePin);
if(FAILED(hr))
{
DbgLog((LOG_TRACE,CONNECT_TRACE_LEVEL,TEXT("CheckConnect failed")));
EXECUTE_ASSERT(SUCCEEDED(BreakConnect()));
return hr;
}
\一個很有用的調(diào)試函數(shù),可以顯示媒體類型
DisplayTypeInfo(pReceivePin,pmt);
\Pin上的媒體類型檢查
hr=CheckMediaType(pmt);
if(hr==NOERROR)
{
m_Connected=pReceivePin;
m_Connected->AddRef();
\在Pin上保存媒體類型
hr=SetMediaType(pmt);
if(SUCCEEDED(hr))
{
\詢問連接對方Pin是否也能接受當(dāng)前的媒體類型
hr=pReceivePin->ReceiveConnection((IPin *)this,pmt);
if(SUCCEEDED(hr))
{
\完成連接
hr=CompleteConnect(pReceivePin);
if(SUCCEEDED(hr))
{
return hr;
}
else
{
DbgLog((LOG_TRACE,CONNECT_TRACE_LEVEL,TEXT("Failed to complete connection")));
pReceivePin->Disconnect();
}
}
}
}
else
{
if(SUCCEEDED(hr)||(hr==E_FAIL)||(hr==E_INVALIDARG))
{
hr=VFW_E_TYPE_NOT_ACCEPTED;
}
}
EXECUTE_ASSERT(SUCCEEDED(BreakConnect()));
if(m_Connected)
{
m_Connected->Release();
m_Connected=NULL:
}
return hr;
}
HRESULT CBaseOutputPin::CompleteConnect(IPin *pReceivePin)
{
UNREFERENCED_PARAMETER(pReceivePin);
return DecideAllocator(m_pInputPin,&m_pAllocator);
}
HRESULT CBaseOutputPin::DecideAllocator(IMemInputPin *pPin,IMemAllocator **ppAlloc)
{
HRESULT hr=NOERROR;
*ppAlloc=NULL;
ALLOCATOR_PROPERTIES prop;
ZeroMemory(&prop,sizeof(prop));
\詢問輸入Pin對分配器的要求
pPin->GetAllocatorRequirements(&prop);
if(prop.cbAlign==0)
{
prop.cbAlign=1;
}
\詢問輸入Pin是否提供一個分配器
hr=pPin->GetAllocator(ppAlloc);
if(SUCCEEDED(hr))
{
\決定Sample使用的內(nèi)存大小,以及分配器管理的Sample數(shù)量
hr=DecideBufferSize(*ppAlloc,&prop);
if(SUCCEEDED(hr))
{
\通知輸入Pin最終使用的分配器對象
hr=pPin->NotifyAllocator(*ppAlloc,FALSE);
if(SUCCEEDED(hr))
{
return NOERROR;
}
}
}
\如果輸入Pin上不提供分配器,則必須在輸出Pin上創(chuàng)建一個分配器
if(*ppAlloc)
{
(*ppAlloc)->Release();
*ppAlloc=NULL;
}
\創(chuàng)建一個輸出Pin上的分配器
hr=InitAllocator(ppAlloc);
if(SUCCEEDED(hr))
{
hr=DecideBufferSize(*ppAlloc,&prop);
if(SUCCEEDED(hr))
{
hr=pPin->NotifyAllocator(*ppAlloc,FALSE);
if(SUCCEEDED(hr))
{
return NOERROR;
}
}
}
if(*ppAlloc)
{
(*ppAlloc)->Release();
*ppAlloc=NULL;
}
return hr;
}
HRESULT CBaseOutputPin::Active(void)
{
if(m_pAllocator==NULL)
{
return VFW_E_NO_ALLOCATOR;
}
return m_pAllocator->Commit();
}
總結(jié)
以上是生活随笔為你收集整理的DirectShow2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ 向量的值逆序输出_C++中vec
- 下一篇: java生成密码_java生成密码生成