Reputation: 1645
For Video mixing renderer, I have
//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 );
and it works, but I cannot make the same using a derived class of baseclasses CBaseRenderer
. Reading the reference pages, I tried to implement IKsPropertySet
interface on the renderer, but it is never queried so that's about it...
So how to enable frame stepping on a custom renderer?
I'm also curious to know how to implement the actual stepping.
For a dirty quick solution, due to the fact that I seem to own a direct pointer to the renderer, I just call
//CBaseRenderer * m_pRenderer
m_pRenderer->BeginFlush();
m_pRenderer->EndFlush();
from the application thread. It works until I switch from stepping state (=paused) to playing state. Essentially, it never breaks down, but there seems to be a lag equal to the duration of the stepping state. Obviously it is not correct.
Upvotes: 4
Views: 242
Reputation: 1645
Ok, I got it after I found EC_STEP_COMPLETE
notification. So this'll do it.
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;
}
Upvotes: 4