다음을 통해 공유


필터 상태

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngineMedia Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

필터에는 중지, 일시 중지 및 실행의 세 가지 가능한 상태가 있습니다. 일시 중지된 상태의 목적은 그래프의 데이터를 큐로 표시하여 실행 명령이 즉시 응답하도록 하는 것입니다. Filter Graph Manager는 모든 상태 전환을 제어합니다. 애플리케이션이 IMediaControl::Run, IMediaControl::P ause 또는 IMediaControl::Stop을 호출하는 경우 Filter Graph Manager는 모든 필터에서 해당 IMediaFilter 메서드를 호출합니다. 중지된 그래프와 실행 간의 전환은 항상 일시 중지된 상태를 거치므로 애플리케이션이 중지된 그래프에서 실행을 호출하는 경우 필터 그래프 관리자는 그래프를 실행하기 전에 일시 중지합니다.

대부분의 필터에서 실행 중 및 일시 중지된 상태는 동일합니다. 다음 필터 그래프를 고려합니다.

원본 > 변환 > 렌더러

이제 원본 필터가 라이브 캡처 원본이 아니라고 가정합니다. 원본 필터가 일시 중지되면 새 데이터를 생성하고 가능한 한 빨리 미디어 샘플에 쓰는 스레드를 만듭니다. 스레드는 변환 필터의 입력 핀에서 IMemInputPin::Receive 를 호출하여 샘플을 다운스트림으로 "푸시"합니다. 변환 필터는 원본 필터의 스레드에서 샘플을 받습니다. 작업자 스레드를 사용하여 렌더러에 샘플을 전달할 수 있지만 일반적으로 동일한 스레드에서 샘플을 제공합니다. 렌더러가 일시 중지되는 동안 샘플을 받기 위해 대기합니다. 하나를 수신한 후에는 해당 샘플을 차단하고 무기한 보유합니다. 비디오 렌더러인 경우 필요에 따라 이미지를 다시 그리는 포스터 이미지로 샘플을 표시합니다.

이 시점에서 스트림은 완전히 큐에 연결되고 렌더링할 준비가 된 것입니다. 그래프가 일시 중지된 상태로 유지되면 Receive 또는 IMemAllocator::GetBuffer에서 모든 필터가 차단될 때까지 샘플이 첫 번째 샘플 뒤에 있는 그래프에 "쌓이게"됩니다. 하지만 데이터가 손실되지 않습니다. 원본 스레드가 차단 해제되면 차단된 지점에서 다시 시작됩니다.

원본 필터와 변환 필터는 일시 중지에서 실행으로의 전환을 무시합니다. 이 필터는 데이터를 가능한 한 빨리 계속 처리합니다. 그러나 렌더러가 실행되면 샘플 렌더링이 시작됩니다. 먼저 일시 중지된 동안 보유한 샘플을 렌더링합니다. 그런 다음 새 샘플을 받을 때마다 샘플의 프레젠테이션 시간을 계산합니다. 자세한 내용은 DirectShow의 시간 및 시계를 참조하세요. 렌더러는 프레젠테이션 시간까지 각 샘플을 보유하며, 이 시점에서 샘플을 렌더링합니다. 프레젠테이션 시간을 기다리는 동안 Receive 메서드에서 차단하거나 큐가 있는 작업자 스레드에서 새 샘플을 받습니다. 렌더러에서 업스트림 필터는 예약에 포함되지 않습니다.

캡처 디바이스와 같은 라이브 소스는 이 일반 아키텍처의 예외입니다. 라이브 원본을 사용하면 데이터를 미리 큐에 추가하는 것은 적절하지 않습니다. 애플리케이션은 그래프를 일시 중지한 다음, 실행하기 전에 오랜 시간 동안 기다릴 수 있습니다. 그래프는 "부실" 샘플을 렌더링해서는 안 됩니다. 따라서 라이브 소스는 실행하는 동안에만 일시 중지되는 동안 샘플을 생성하지 않습니다. 이 사실을 Filter Graph Manager에 알리기 위해 원본 필터의 IMediaFilter::GetState 메서드는 VFW_S_CANT_CUE 반환합니다. 이 반환 코드는 렌더러가 데이터를 수신하지 않았더라도 필터가 일시 중지된 상태로 전환되었음을 나타냅니다.

필터가 중지되면 필터에 전달된 샘플을 더 이상 거부합니다. 원본 필터는 스트리밍 스레드를 종료하고 다른 필터는 만든 작업자 스레드를 종료합니다. 고정은 할당자를 커밋 해제합니다.

상태 전환

Filter Graph Manager는 렌더러에서 시작하여 원본 필터로 뒤로 작업하는 업스트림 순서로 모든 상태 전환을 수행합니다. 이 순서는 샘플이 삭제되는 것을 방지하고 그래프가 교착 상태에 빠지지 않도록 하는 데 필요합니다. 가장 중요한 상태 전환은 일시 중지와 중지 사이입니다.

  • 일시 중지됨: 각 필터가 일시 중지되면 다음 필터에서 샘플을 받을 준비가 됩니다. 원본 필터가 마지막으로 일시 중지됩니다. 스트리밍 스레드를 만들고 샘플 제공을 시작합니다. 모든 다운스트림 필터가 일시 중지되므로 필터가 샘플을 거부하지 않습니다. 필터 그래프 관리자는 그래프의 모든 렌더러가 샘플을 받을 때까지 전환을 완료하지 않습니다(앞서 설명한 대로 라이브 원본 제외).
  • 중지됨: 필터가 중지되면 보류 중인 모든 샘플을 해제하여 GetBuffer에서 대기 중인 업스트림 필터의 차단을 해제합니다. 필터가 Receive 메서드 내에서 리소스를 기다리는 경우 대기가 중지되고 호출 필터의 차단을 해제하는 Receive에서 반환됩니다. 따라서 필터 그래프 관리자가 다음 업스트림 필터를 중지하면 해당 필터는 GetBuffer 또는 Receive에서 차단되지 않으며 stop 명령에 응답할 수 있습니다. 업스트림 필터는 중지 명령을 가져오기 전에 몇 가지 추가 샘플을 제공할 수 있지만 다운스트림 필터는 이미 중지되었기 때문에 단순히 거부합니다.

필터 그래프의 Data Flow