mainactual
mainactual

Reputation: 1645

Implementing frame step on CBaseRenderer

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

Answers (1)

mainactual
mainactual

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

Related Questions