Как правильно поддерживать очистку в фильтре 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();
}