日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

DirectShow2

發(fā)布時間:2023/12/13 综合教程 23 生活家
生活随笔 收集整理的這篇文章主要介紹了 DirectShow2 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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);
\檢查該Pin是否已連接
if(m_Connected)
{
DbgLog((LOG_TRACE,CONNECT_TRACE_LEVEL,TEXT("Already connected")));
return VFW_E_ALREADY_CONNECTED;
}
\一般Filter只能在停止狀態(tài)下進行連接
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()))
{
\用這個完全指定的媒體類型進行試連接,如果試連接失敗,不再作其他嘗試
return AttemptConnection(pReceivePin,pmt);
}
HRESULT hrFailure=VFW_E_NO_ACCEPTABLE_TYPES;
\進行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);
\檢查當前枚舉得到的媒體類型是否與不完全指定的媒體類型參數(shù)匹配
if((pmt==NULL)||pMediaType->MatchesPartial(pmt))
{
\進行試連接
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是否也能接受當前的媒體類型
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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。