다음을 통해 공유


샘플 제공

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

이 문서에서는 필터가 샘플을 제공하는 방법을 설명합니다. IMemInputPin 메서드를 사용하는 푸시 모델과 IAsyncReader사용하는 끌어오기 모델을 모두 설명합니다.

푸시 모델: 샘플 전달

출력 핀은 IMemInputPin::Receive 메서드 또는 IMemInputPin::ReceiveMultiple 메서드를 호출하여 샘플을 제공합니다. 이 메서드는 동일하지만 샘플 배열을 제공합니다. 입력 핀은 수신(또는 다중 수신) 내부를 차단할 수 있습니다. 핀이 차단될 수 있는 경우 해당 IMemInputPin::ReceiveCanBlock 메서드는 S_OK 반환해야 합니다. 핀이 차단되지 않도록 보장하는 경우 ReceiveCanBlock S_FALSE 반환해야 합니다. S_OK 반환 값은 수신이 항상 차단된다는 의미는 아니지만, 가능성이 있음을 나타냅니다.

수신 리소스가 사용 가능해질 때까지 기다리도록 차단할 수 있지만 업스트림 필터에서 더 많은 데이터를 기다리는 것을 차단해서는 안 됩니다. 이렇게 하면 업스트림 필터가 다운스트림 필터가 샘플을 해제할 때까지 대기하는 교착 상태가 발생할 수 있습니다. 이는 다운스트림 필터가 업스트림 필터에서 대기 중이기 때문에 발생하지 않습니다. 그러나 필터에 입력 핀이 여러 개 있는 경우 한 핀은 다른 핀이 데이터를 받을 때까지 기다릴 수 있습니다. 예를 들어 AVI Mux 필터는 오디오 및 비디오 데이터를 인터리브할 수 있도록 이 작업을 수행합니다.

핀은 다음과 같은 여러 가지 이유로 샘플을 거부할 수 있습니다.

  • 핀이 플러시되고 있습니다(플러시참조).
  • 핀이 연결되지 않았습니다.
  • 필터가 중지되었습니다.
  • 다른 오류가 발생했습니다.

Receive 메서드는 첫 번째 사례에서 S_FALSE 반환하고 다른 경우에는 실패 코드를 반환해야 합니다. 반환 코드가 S_OK 이외의 경우 업스트림 필터는 샘플 전송을 중지해야 합니다.

필터가 샘플을 수신하는 상태가 잘못되었다는 점에서 처음 세 가지 경우를 "예상" 실패로 간주할 수 있습니다. 예기치 않은 실패는 핀이 수신 상태에 있더라도 핀이 샘플을 거부하게 하는 오류입니다. 이 유형의 오류가 발생하면 핀은 스트림 종료 알림 다운스트림을 보내고 필터 그래프 관리자에 EC_ERRORABORT 이벤트를 보내야 합니다.

DirectShow 기본 클래스에서 CBaseInputPin::CheckStreaming 메서드는 일반적인 오류 사례(플러시, 중지 등)를 확인합니다. 파생 클래스는 필터와 관련된 오류를 확인해야 합니다. 오류가 발생할 경우 CBaseInputPin::Receive 메서드는 스트림 끝 알림 및 EC_ERRORABORT 이벤트를 보냅니다.

끌어오기 모델: 샘플 요청하기

IAsyncReader 인터페이스에서 입력 핀은 다음 방법 중 하나를 호출하여 출력 핀에서 샘플을 요청합니다.

Request 메서드는 비동기입니다. 입력 핀은 요청이 완료되기를 기다리기 위해 IAsyncReader::WaitForNext를 호출합니다. 다른 두 메서드는 동기적입니다.

데이터 전달 시점

필터는 실행 중인 상태에서 항상 샘플을 제공합니다. 대부분의 경우 필터는 일시 중지된 동안 샘플을 제공합니다. 이렇게 하면 그래프가 데이터를 큐에 표시함으로써 실행 함수가 호출될 때 즉시 재생이 시작됩니다(필터 상태 참조). 필터가 일시 중지된 동안 데이터를 제공하지 않는 경우 필터의 IMediaFilter::GetState 메서드는 일시 중지된 상태에서 VFW_S_CANT_CUE 반환해야 합니다. 이 반환 코드는 필터 그래프가 일시 중지 전환을 완료하기 전에 필터의 데이터를 기다리지 않도록 신호를 표시합니다. 그렇지 않으면 Pause 메서드가 무기한 차단됩니다. 예제 코드는 CBaseFilter::GetState참조하세요.

필터가 VFW_S_CANT_CUE 반환해야 하는 경우의 몇 가지 예는 다음과 같습니다.

  • 캡처 필터와 같은 라이브 원본은 일시 중지된 동안 데이터를 보내지 않아야 합니다. 캡처 필터 에서 데이터 생성을 참조하세요.
  • 분할자 필터는 구현에 따라 일시 중지된 동안 데이터를 보낼 수도 있고 전송되지 않을 수도 있습니다. 필터가 별도의 스레드를 사용하여 각 출력 핀의 데이터를 큐에 대기하는 경우 일시 중지된 동안 데이터를 보낼 수 있습니다. 그러나 필터가 모든 출력 핀에 단일 스레드를 사용하는 경우 첫 번째 핀은 수신호출할 때 스레드를 차단하여 다른 핀이 데이터를 보내지 못하게 할 수 있습니다. 당신은 이 경우 VFW_S_CANT_CUE를 반환해야 합니다.
  • 필터는 산발적으로 데이터를 제공할 수 있습니다. 예를 들어 사용자 지정 데이터 스트림을 구문 분석하고 일부 패킷을 필터링하면서 다른 패킷을 배달할 수 있습니다. 이 경우 일시 중지된 동안 필터가 데이터를 배달하도록 보장되지 않을 수 있습니다.

소스 필터(푸시 모델 사용) 또는 파서 필터(밀어넣기/끌어오기 모델 사용)는 하나 이상의 스트리밍 스레드를 만들어 샘플을 가능한 한 빨리 제공합니다. 디코더 및 변환과 같은 다운스트림 필터는 일반적으로 입력 핀에서 수신 호출되는 경우에만 데이터를 보냅니다.

샘플 수신 및 전달