WDM 클래스 드라이버 필터

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

캡처 디바이스에서 WDM(Windows 드라이버 모델) 드라이버를 사용하는 경우 그래프에는 캡처 필터에서 업스트림 특정 필터가 필요할 수 있습니다. 이러한 필터를 스트림 클래스 드라이버 필터 또는 WDM 필터라고 합니다. 하드웨어에서 제공하는 추가 기능을 지원합니다. 예를 들어 TV 튜너 카드 채널 설정에 대한 함수가 있습니다. 해당 필터는 IAMTVTuner 인터페이스를 노출하는 TV 튜너 필터입니다. 이 기능을 애플리케이션에서 사용할 수 있도록 하려면 TV 튜너 필터를 캡처 필터에 연결해야 합니다.

ICaptureGraphBuilder2 인터페이스는 그래프에 WDM 필터를 추가하는 가장 쉬운 방법을 제공합니다. 그래프를 빌드하는 동안 어느 시점에서 FindInterface 또는 RenderStream을 호출합니다. 이러한 방법 중 하나는 필요한 WDM 필터를 자동으로 찾아 캡처 필터에 연결합니다. 이 섹션의 나머지 부분에서는 WDM 필터를 수동으로 추가하는 방법을 설명합니다. 그러나 권장 방법은 단순히 이러한 ICaptureGraphBuilder2 메서드 중 하나를 호출하는 것입니다.

WDM 필터의 핀은 하나 이상의 매체를 지원합니다. 매체는 버스와 같은 통신 방법을 정의합니다. 동일한 매체를 지원하는 핀을 연결해야 합니다. 커널 스트리밍 드라이버에 사용되는 KSPIN_MEDIUM 구조와 동일한 REGPINMEDIUM 구조체는 DirectShow에서 매체를 정의합니다. REGPINMEDIUM 구조체의 clsMedium 멤버는 매체에 대한 CLSID(클래스 식별자)를 지정합니다. 핀의 매체를 검색하려면 IKsPin::KsQueryMediums 메서드를 호출합니다 . 이 메서드는 KSMULTIPLE_ITEM 구조체와 0개 이상의 REGPINMEDIUM 구조체가 포함된 메모리 블록에 대한 포인터를 반환합니다. 각 REGPINMEDIUM 구조체는 핀이 지원하는 매체를 식별합니다.

매체에 GUID_NULL 또는 KSMEDIUMSETID_Standard CLSID가 있는 경우 핀을 연결하지 마세요. 핀이 매체를 지원하지 않음을 나타내는 기본값입니다.

또한 필터에 해당 핀의 연결된 instance 정확히 하나만 필요하지 않으면 핀을 연결하지 마세요. 그렇지 않으면 애플리케이션이 연결하면 안 되는 다양한 핀을 연결하려고 할 수 있으며, 이로 인해 프로그램이 응답하지 않을 수 있습니다. 필요한 인스턴스 수를 확인하려면 다음 코드 예제와 같이 KSPROPERTY_PIN_NECESSARYINSTANCES 속성 집합을 검색합니다. (간단히 하기 위해 이 예제에서는 반환 코드를 테스트하거나 인터페이스를 해제하지 않습니다. 애플리케이션은 물론 두 가지 작업을 모두 수행해야 합니다.)

// Obtain the pin factory identifier.
IKsPinFactory *pPinFactory;
hr = pPin->QueryInterface(IID_IKsPinFactory, (void **)&pPinFactory);

ULONG ulFactoryId;
hr = pPinFactory->KsPinFactory(&ulFactoryId);

// Get the "instance" property from the filter.
IKsControl *pKsControl;
hr = pFilter->QueryInterface(IID_IKsControl, (void **)&pKsControl);

KSP_PIN ksPin;
ksPin.Property.Set = KSPROPSETID_Pin;
ksPin.Property.Id = KSPROPERTY_PIN_NECESSARYINSTANCES;
ksPin.Property.Flags = KSPROPERTY_TYPE_GET;
ksPin.PinId = ulFactoryId;
ksPin.Reserved = 0; 

KSPROPERTY ksProp;
ULONG ulInstances, bytes;
pKsControl->KsProperty((PKSPROPERTY)&ksPin, sizeof(ksPin), 
    &ulInstances, sizeof(ULONG), &bytes);

if (hr == S_OK && bytes == sizeof(ULONG)) 
{
    if (ulInstances == 1) 
    {
        // Filter requires one instance of this pin.
        // This pin is OK.
    } 
}

다음 의사 코드는 WDM 필터를 찾아 연결하는 방법을 보여 주는 매우 간단한 개요입니다. 많은 세부 정보를 생략하며 애플리케이션에서 수행해야 하는 일반적인 단계만 표시하기 위한 것입니다.

Add supporting filters:
{
    foreach input pin:
        skip if (pin is connected)
    
        Get pin medium
        skip if (medium is GUID_NULL or KSMEDIUMSETID_Standard)
    
        Query filter for KSPROPERTY_PIN_NECESSARYINSTANCES property
        skip if (necessary instances != 1)

        Match an existing pin || Find a matching filter
}    

Match an existing pin:
{
    foreach filter in the graph
        foreach unconnected pin
            Get pin medium
            if (mediums match)
                connect the pins    
}

Find a matching filter:
{    
    Query the filter graph manager for IFilterMapper2.
    Find a filter with an output pin that matches the medium.
    Add the filter to the graph.
    Connect the pins.
    Add supporting filters. (Recursive call.)
}

고급 캡처 항목