다음을 통해 공유


샘플 제공

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

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

푸시 모델: 샘플 제공

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

수신은 리소스가 사용 가능해질 때까지 대기하도록 차단할 수 있지만 업스트림 필터에서 더 많은 데이터를 대기하도록 차단해서는 안 됩니다. 이렇게 하면 업스트림 필터가 다운스트림 필터가 샘플을 해제할 때까지 대기하는 교착 상태가 발생할 수 있으며, 이는 다운스트림 필터가 업스트림 필터에서 대기하고 있기 때문에 발생하지 않습니다. 그러나 필터에 여러 개의 입력 핀이 있는 경우 한 핀은 다른 핀이 데이터를 받을 때까지 기다릴 수 있습니다. 예를 들어 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 반환해야 하는 경우의 몇 가지 예는 다음과 같습니다.

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

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

샘플 수신 및 제공