Как правильно поддерживать очистку в фильтре DirectShow с несколькими входными контактами

На странице MSDN, посвященной соображениям о потоке фильтров для очистки данных, предлагается реализация BeginFlush и EndFlush для фильтра с одним входным контактом и одним или несколькими выходными контактами.

Как это можно безопасно расширить для фильтра с несколькими входными контактами? Должны ли 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 ответ

Решение

В моем коде я просто тупо поставляю флеш вниз по течению для каждого, что получаю. Вроде работает без проблем.

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();
}
Другие вопросы по тегам