DirecShow4 Stop、Pause、Run的实现
//Filter调用Stop,实际上就是调用Filter的所有Pin的Inactive函数
STDMETHODIMP CBaseFilter::Stop()
{
CAutoLock cObjectLock(m_pLock);
HRESULT hr=NOERROR;
//notify all pins of the state change
if(m_State!=State_Stopped)
{
int cPins=GetPinCount();
for(int c=0;c<cPins;c++)
{
CBasePin *pPin=GetPin(c);
//仅在完成连接的Pin上调用Inactive函数,如果Inactive函数返回一个错误值,则暂时
//忽略,以使所有Pin都有机会被调用Inactive
if(pPin->IsConnected())
{
HRESULT hrTmp=pPin->Inactive();
if(FAILED(hrTmp)&&SUCCEEDED(hr))
{
hr=hrTmp;
}
}
}
}
m_State=State_Stopped;
return hr;
}
STDMETHODIMP CBaseFilter::Stop()
{
CAutoLock cObjectLock(m_pLock);
HRESULT hr=NOERROR;
//notify all pins of the state change
if(m_State!=State_Stopped)
{
int cPins=GetPinCount();
for(int c=0;c<cPins;c++)
{
CBasePin *pPin=GetPin(c);
//仅在完成连接的Pin上调用Inactive函数,如果Inactive函数返回一个错误值,则暂时
//忽略,以使所有Pin都有机会被调用Inactive
if(pPin->IsConnected())
{
HRESULT hrTmp=pPin->Inactive();
if(FAILED(hrTmp)&&SUCCEEDED(hr))
{
hr=hrTmp;
}
}
}
}
m_State=State_Stopped;
return hr;
}
//Filter调用Pause,实际上就是调用Filter的所有Pin的Active函数
STDMETHODIMP CBaseFilter::Pause()
{
CAutoLock cObjectLock(m_pLock);
//notify all pins of the change to active state
if(m_State==State_Stopped)
{
int cPins=GetPinCount();
for(int c=0;c<cPins;c++)
{
CBasePin *pPin=GetPin(c);
//仅在完成连接的Pin上调用Active函数,如果其中有一个Pin上的Active函数调用
//失败,则让CBaseFilter::Pause直接返回这个错误值
if(pPin->IsConnected())
{
HRESULT hr=pPin->Active();
if(FAILED(hr))
{
return hr;
}
}
}
}
m_State=State_Paused;
return S_OK;
}
STDMETHODIMP CBaseFilter::Pause()
{
CAutoLock cObjectLock(m_pLock);
//notify all pins of the change to active state
if(m_State==State_Stopped)
{
int cPins=GetPinCount();
for(int c=0;c<cPins;c++)
{
CBasePin *pPin=GetPin(c);
//仅在完成连接的Pin上调用Active函数,如果其中有一个Pin上的Active函数调用
//失败,则让CBaseFilter::Pause直接返回这个错误值
if(pPin->IsConnected())
{
HRESULT hr=pPin->Active();
if(FAILED(hr))
{
return hr;
}
}
}
}
m_State=State_Paused;
return S_OK;
}
//Filter调用Run,实际上就是调用Filter的所有Pin的Run函数
STDMETHODIMP CBaseFilter::Run(REFERENCE_TIME tStart)
{
CAutoLock cObjectLock(m_pLock);
//remember the stream time offset
m_tStart=tStart;
//暂停状态是Filter从停止到运行切换的必经状态!
if(m_State==State_Stopped)
{
HRESULT hr=Pause();
if(FAILED(hr))
{
return hr;
}
}
//notify all pins of the change to active state
if(m_State!=State_Running)
{
int cPins=GetPinCount();
for(int c=0;c<cPins;c++)
{
CBasePin *pPin=GetPin(c);
//仅在完成连接的Pin上调用Run函数
if(pPin->IsConnected())
{
HRESULT hr=pPin->Run(tStart);
if(FAILED(hr))
{
return hr;
}
}
}
}
m_State=State_Running;
return S_OK;
}
STDMETHODIMP CBaseFilter::Run(REFERENCE_TIME tStart)
{
CAutoLock cObjectLock(m_pLock);
//remember the stream time offset
m_tStart=tStart;
//暂停状态是Filter从停止到运行切换的必经状态!
if(m_State==State_Stopped)
{
HRESULT hr=Pause();
if(FAILED(hr))
{
return hr;
}
}
//notify all pins of the change to active state
if(m_State!=State_Running)
{
int cPins=GetPinCount();
for(int c=0;c<cPins;c++)
{
CBasePin *pPin=GetPin(c);
//仅在完成连接的Pin上调用Run函数
if(pPin->IsConnected())
{
HRESULT hr=pPin->Run(tStart);
if(FAILED(hr))
{
return hr;
}
}
}
}
m_State=State_Running;
return S_OK;
}