The MSDN page about Filter threading considerations for flushing data gives a suggested implementation of BeginFlush and EndFlush for a filter with single input pin and one or more output pins.
How should this be extended safely for a filter with multiple input pins? Should DeliverBeginFlush and DeliverEndFlush be called for every input pin, or for the first or last input pin to receive BeginFlush/EndFlush? Is the exact sequence of operations between input pins important? Is it allowable for one input pin to finish both BeginFlush and EndFlush and receive new samples before other pins have received BeginFlush and/or EndFlush? Are there any other considerations or gotchas in this situation?
At the moment my filter with multiple input pins is sometimes receiving stale queued samples from upstream after EndFlush has completed and I’m trying to diagnose whether the bug is in my filter or further upstream. The input pins are queueing samples for another thread that generates output samples so I do make use of the m_hSomeEventThatReceiveNeedsToWaitOn technique to unblock the thread that does output processing.
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();
}
In my code I just dumbly deliver a flush downstream for every one I receive. It seems to work without problems.