Очистка данных
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
В следующем псевдокоде показано, как реализовать метод IPin::BeginFlush :
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;
}
При запуске очистки метод BeginFlush принимает блокировку фильтра, которая сериализует изменение состояния. Блокировка потоковой передачи пока небезопасна, так как очистка происходит в потоке приложения, а поток потоковой передачи может находиться в середине вызова приема . Пин-код должен гарантировать, что получение не будет заблокировано и что все последующие вызовы receive завершатся ошибкой. Метод CBaseInputPin::BeginFlush устанавливает внутренний флаг CBaseInputPin::m_bFlushing. Если флаг имеет значение TRUE, метод Receive завершается ошибкой.
Доставляя подчиненный вызов BeginFlush , закрепление гарантирует, что все подчиненные фильтры отпустят свои примеры и возвращаются из приема вызовов. Это, в свою очередь, гарантирует, что входной пин-код не будет заблокирован в ожидании GetBuffer или Receive. Если метод получения вашего контакта когда-либо ожидает события (например, для получения ресурсов), метод BeginFlush должен принудительно завершить ожидание, задав событие. На этом этапе метод Receive гарантированно возвращается, а флаг m_bFlushing не позволяет новым вызовам Receive выполнять какие-либо действия.
Для некоторых фильтров это все, что нужно сделать BeginFlush . Метод EndFlush сообщит фильтру о том, что он может снова начать получать образцы. Другим фильтрам может потребоваться использовать переменные или ресурсы в BeginFlush , которые также используются в receive. В этом случае фильтр должен сначала удерживать блокировку потоковой передачи. Не делайте этого перед предыдущими шагами, так как это может привести к взаимоблокировкам.
Метод EndFlush удерживает блокировку фильтра и распространяет вызов ниже:
HRESULT CMyInputPin::EndFlush()
{
CAutoLock lock_it(m_pLock);
for (each output pin)
hr = pOutputPin->DeliverEndFlush();
return CBaseInputPin::EndFlush();
}
Метод CBaseInputPin::EndFlush сбрасывает флаг m_bFlushing на FALSE, что позволяет методу Receive снова начать получение примеров. Это должен быть последний шаг в EndFlush, так как закрепление не должно получать какие-либо образцы, пока не будет завершена очистка и все подчиненные фильтры не будут уведомлены.