在 CBaseRenderer 上实现帧步骤
Implementing frame step on CBaseRenderer
对于视频混合渲染器,我有
//IFilterGraph * m_FilterGraph
IVideoFrameStep * ivfs=0;
HRESULT hr = m_FilterGraph->QueryInterface(IID_IVideoFrameStep, (void**)&ivfs );
if ( SUCCEEDED(hr) )
{
ivfs->Step( 1, 0 );
}
SAFE_RELEASE( ivfs );
它可以工作,但我不能使用 baseclasses CBaseRenderer
的派生 class 来做同样的事情。阅读参考页面,我尝试在渲染器上实现 IKsPropertySet
接口,但它从未被查询过,所以就是这样......
那么如何在自定义渲染器上启用帧步进?
我也很想知道如何实现实际的步进。
对于肮脏的快速解决方案,由于我似乎拥有指向渲染器的直接指针,我只调用
//CBaseRenderer * m_pRenderer
m_pRenderer->BeginFlush();
m_pRenderer->EndFlush();
来自应用程序线程。它一直有效,直到我从步进状态(=暂停)切换到播放状态。本质上,它永远不会崩溃,但似乎有一个滞后等于步进状态的持续时间。显然是不正确的。
好的,我找到EC_STEP_COMPLETE
通知后就知道了。这样就可以了。
STDMETHODIMP CSteppingBaseRenderer::NonDelegatingQueryInterface(const IID &riid, void **ppv){
if (!ppv)
return E_POINTER;
if ( riid == IID_IKsPropertySet ){
return GetInterface( (IKsPropertySet*)this, ppv );
}
return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv);
}
STDMETHODIMP CSteppingBaseRenderer::Set(
REFGUID guidPropSet,
DWORD dwPropID,
LPVOID pInstanceData,
DWORD cbInstanceData,
LPVOID pPropData,
DWORD cbPropData)
{
if ( guidPropSet == AM_KSPROPSETID_FrameStep )
{
if (dwPropID == AM_PROPERTY_FRAMESTEP_STEP )
{
m_Stepping = 1;
return S_OK;
}else if ( dwPropID == AM_PROPERTY_FRAMESTEP_CANSTEP )
{
return S_OK;
}
}
return E_PROP_SET_UNSUPPORTED;
}
HRESULT CSteppingBaseRenderer::DoRenderSample(IMediaSample *pMediaSample){
//...
if ( m_Stepping && !(--m_Stepping) )
{
this->NotifyEvent( EC_STEP_COMPLETE, 0, 0 );
}
return NOERROR;
}
对于视频混合渲染器,我有
//IFilterGraph * m_FilterGraph
IVideoFrameStep * ivfs=0;
HRESULT hr = m_FilterGraph->QueryInterface(IID_IVideoFrameStep, (void**)&ivfs );
if ( SUCCEEDED(hr) )
{
ivfs->Step( 1, 0 );
}
SAFE_RELEASE( ivfs );
它可以工作,但我不能使用 baseclasses CBaseRenderer
的派生 class 来做同样的事情。阅读参考页面,我尝试在渲染器上实现 IKsPropertySet
接口,但它从未被查询过,所以就是这样......
那么如何在自定义渲染器上启用帧步进?
我也很想知道如何实现实际的步进。
对于肮脏的快速解决方案,由于我似乎拥有指向渲染器的直接指针,我只调用
//CBaseRenderer * m_pRenderer
m_pRenderer->BeginFlush();
m_pRenderer->EndFlush();
来自应用程序线程。它一直有效,直到我从步进状态(=暂停)切换到播放状态。本质上,它永远不会崩溃,但似乎有一个滞后等于步进状态的持续时间。显然是不正确的。
好的,我找到EC_STEP_COMPLETE
通知后就知道了。这样就可以了。
STDMETHODIMP CSteppingBaseRenderer::NonDelegatingQueryInterface(const IID &riid, void **ppv){
if (!ppv)
return E_POINTER;
if ( riid == IID_IKsPropertySet ){
return GetInterface( (IKsPropertySet*)this, ppv );
}
return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv);
}
STDMETHODIMP CSteppingBaseRenderer::Set(
REFGUID guidPropSet,
DWORD dwPropID,
LPVOID pInstanceData,
DWORD cbInstanceData,
LPVOID pPropData,
DWORD cbPropData)
{
if ( guidPropSet == AM_KSPROPSETID_FrameStep )
{
if (dwPropID == AM_PROPERTY_FRAMESTEP_STEP )
{
m_Stepping = 1;
return S_OK;
}else if ( dwPropID == AM_PROPERTY_FRAMESTEP_CANSTEP )
{
return S_OK;
}
}
return E_PROP_SET_UNSUPPORTED;
}
HRESULT CSteppingBaseRenderer::DoRenderSample(IMediaSample *pMediaSample){
//...
if ( m_Stepping && !(--m_Stepping) )
{
this->NotifyEvent( EC_STEP_COMPLETE, 0, 0 );
}
return NOERROR;
}