Поделиться через


Очистка данных

[Функция, связанная с этой страницей 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, так как закрепление не должно получать какие-либо образцы, пока не будет завершена очистка и все подчиненные фильтры не будут уведомлены.

Потоки и критические разделы