共用方式為


WDM 類別驅動程序篩選

[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、imfMediaEngine 取代,並在媒體基金會 音訊/視訊擷取。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayerIMFMediaEngine 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

如果擷取裝置使用 Windows 驅動程式模型 (WDM) 驅動程式,圖表可能需要從擷取篩選器上游的特定篩選。 這些篩選稱為數據流類別驅動程式篩選器或 WDM 篩選條件。 它們支持硬體所提供的其他功能。 例如,電視微調卡具有設定頻道的功能。 對應的篩選條件是 TV Tuner 篩選,它會公開 IAMTVTuner 介面。 若要讓此功能可供應用程式使用,您必須將TV Tuner篩選器連線到擷取篩選器。

ICaptureGraphBuilder2 介面提供將 WDM 篩選新增至圖形的最簡單方式。 在建置圖形時,呼叫 FindInterfaceRenderStream。 其中一種方法會自動找出必要的 WDM 篩選器,並將其連線到擷取篩選。 本節的其餘部分說明如何手動新增 WDM 篩選器。 不過,請注意,建議的方法只是呼叫下列其中一個 ICaptureGraphBuilder2 方法。

WDM 篩選器上的針腳支援一或多個媒體。 媒體會定義通訊方法,例如總線。 您必須連接支援相同媒體的針腳。 REGPINMEDIUM 結構,相當於用於核心串流驅動程式的 KSPIN_MEDIUM 結構,在 DirectShow 中定義媒體。 clsMediumREGPINMEDIUM 結構的成員會指定媒體的類別識別碼 (CLSID)。 若要擷取針腳的媒體,請呼叫 IKsPin::KsQueryMediums 方法。 這個方法會傳回記憶體區塊的指標,其中包含 KSMULTIPLE_ITEM 結構,後面接著零個或多個 REGPINMEDIUM 結構。 每個 REGPINMEDIUM 結構都會識別針腳支持的媒體。

如果媒體的 CLSID 為 GUID_NULL 或 KSMEDIUMSETID_Standard,請勿連接針腳。 這些是預設值,表示針腳不支持媒體。

此外,除非篩選只需要該針腳的一個連接實例,否則請勿連接針腳。 否則,您的應用程式可能會嘗試連接不應該有連線的各種針腳,這可能會導致程式停止回應。 若要找出所需的實例數目,請擷取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.)
}

進階擷取主題