在CBaseRenderer上实现框架步骤

时间:2016-03-06 18:53:24

标签: c++ windows directshow

对于视频混合渲染器,我有

//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 );

并且它有效,但我不能使用派生类的基类CBaseRenderer来做同样的事情。阅读参考页面时,我尝试在渲染器上实现IKsPropertySet接口,但是从不查询它以便关于它......

那么如何在自定义渲染器上启用帧步进?

我也很想知道如何实施实际步骤。

对于一个肮脏的快速解决方案,由于我似乎拥有一个指向渲染器的直接指针,我只需要调用

//CBaseRenderer * m_pRenderer
m_pRenderer->BeginFlush();
m_pRenderer->EndFlush();

来自应用程序线程。它一直有效,直到我从步进状态(=暂停)切换到播放状态。从本质上讲,它永远不会崩溃,但似乎有一个滞后等于踩踏状态的持续时间。显然这是不正确的。

1 个答案:

答案 0 :(得分:4)

好的,我在找到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;
}