다음을 통해 공유


데이터 비우기

[DirectShow 이 페이지와 연결된 기능은 레거시 기능입니다. MediaPlayer, IMFMediaEngine, Media Foundation 오디오/비디오 캡처대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11에 최적화되었습니다. Microsoft는 가능하면 새로운 코드에서 MediaPlayer, IMFMediaEngineAudio/Video Capture를 DirectShow대신 Media Foundation 사용하는 것이 좋습니다. 가능한 경우 레거시 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 메서드는 상태 변경을 직렬화하는 필터 잠금을 사용합니다. 애플리케이션 스레드에서 플러시가 발생하고 스트리밍 스레드가 수신 호출의 중간에 있을 수 있으므로 스트리밍 잠금을 사용하는 것은 아직 안전하지 않습니다. 핀은 수신 차단되지 않고 수신 대한 후속 호출이 실패하도록 보장해야 합니다. CBaseInputPin::BeginFlush 메서드는 내부 플래그인 CBaseInputPin::m_bFlushing을 설정합니다. 플래그가 TRUE일 때, Receive 메서드가 실패합니다.

핀은 하류로 BeginFlush 호출을 전달하여 모든 하류 필터가 샘플을 방출하고 리시브 호출에서 반환하도록 보장합니다. 그러면 입력 핀이 GetBuffer 또는 Receive를 기다리는 동안 차단되지 않음을 보장합니다. 핀의 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마지막 단계여야 합니다.

스레드 및 중요 섹션