如何在具有多个输入引脚的DirectShow过滤器中正确支持刷新

时间:2013-01-28 16:45:10

标签: visual-c++ directshow

MSDN page about Filter threading considerations for flushing data为具有单个输入引脚和一个或多个输出引脚的滤波器提供了BeginFlushEndFlush的建议实现。

对于具有多个输入引脚的滤波器,应该如何安全地扩展?是应该为每个输入引脚调用DeliverBeginFlush和DeliverEndFlush,还是为第一个或最后一个输入引脚接收BeginFlush / EndFlush?输入引脚之间的确切操作顺序是否重要?是否允许一个输入引脚完成BeginFlush和EndFlush,并在其他引脚收到BeginFlush和/或EndFlush之前接收新的采样?在这种情况下还有其他考虑因素或陷阱吗?

目前,我的带有多个输入引脚的过滤器有时会在EndFlush完成后从上游接收过时的排队样本,并且我正在尝试诊断该错误是在我的过滤器还是在上游。输入引脚为另一个生成输出样本的线程排队样本,因此我确实利用m_hSomeEventThatReceiveNeedsToWaitOn技术来取消阻塞进行输出处理的线程。

HRESULT CMyInputPin::BeginFlush()
{
    CAutoLock lock_it(m_pLock);

    // First, make sure the Receive method will fail from now on.
    HRESULT hr = CBaseInputPin::BeginFlush();

    // Force downstream filters to release samples. If our Receive method
    // is blocked in GetBuffer or Deliver, this will unblock it.
    for (each output pin)
    {
    hr = pOutputPin->DeliverBeginFlush();
    }

    // Unblock our Receive method if it is waiting on an event.
    SetEvent(m_hSomeEventThatReceiveNeedsToWaitOn);

    // At this point, the Receive method can't be blocked. Make sure 
    // it finishes, by taking the streaming lock. (Not necessary if this 
    // is the last step.)
    { 
    CAutoLock lock_2(&m_csReceive);

    /* Now it's safe to do anything that would crash or hang 
       if Receive were executing. */
    }
    return hr;
}

HRESULT CMyInputPin::EndFlush()
{
    CAutoLock lock_it(m_pLock);
    for (each output pin)
        hr = pOutputPin->DeliverEndFlush();
    return CBaseInputPin::EndFlush();
}   

1 个答案:

答案 0 :(得分:1)

在我的代码中,我只是愚蠢地为我收到的每一个下游提供冲洗。它似乎没有问题。

HRESULT JoinFilterInputPin::BeginFlush()
{
    JoinFilter* filter = (JoinFilter*)m_pFilter;
    CAutoLock lock(m_pLock);
    CBaseInputPin::BeginFlush();
    filter->output->DeliverBeginFlush();
    return S_OK;
}

HRESULT JoinFilterInputPin::EndFlush()
{
    JoinFilter* filter = (JoinFilter*)m_pFilter;
    CAutoLock lock(m_pLock);
    filter->output->DeliverEndFlush();
    return CBaseInputPin::EndFlush();
}