Share via


데이터 플러시

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 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 메서드는 필터에 샘플 수신을 다시 시작할 수 있다는 신호를 보냅니다. 다른 필터는 Receive에도 사용되는 BeginFlush의 변수 또는 리소스를 사용해야 할 수 있습니다. 이 경우 필터는 먼저 스트리밍 잠금을 보유해야 합니다. 교착 상태가 발생할 수 있으므로 이전 단계 전에 이 작업을 수행하지 마세요.

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의 마지막 단계여야 합니다.

스레드 및 중요 섹션