WDM 类驱动程序筛选器
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
如果捕获设备使用 Windows 驱动程序模型 (WDM) 驱动程序,则图形可能需要从捕获筛选器上游某些筛选器。 这些筛选器称为流类驱动程序筛选器或 WDM 筛选器。 它们支持硬件提供的其他功能。 例如,电视调谐器卡具有用于设置频道的函数。 相应的筛选器是 电视调谐器 筛选器,它公开 IAMTVTuner 接口。 若要使此功能可供应用程序使用,必须将电视调谐器筛选器连接到捕获筛选器。
ICaptureGraphBuilder2 接口提供了向图形添加 WDM 筛选器的最简单方法。 在生成图形的某个时候,调用 FindInterface 或 RenderStream。 其中任一方法都会自动查找所需的 WDM 筛选器,并将其连接到捕获筛选器。 本部分的其余部分介绍如何手动添加 WDM 筛选器。 但是,请注意,建议的方法只是调用这些 ICaptureGraphBuilder2 方法之一。
WDM 筛选器上的引脚支持一个或多个介质。 媒体定义通信方法,例如总线。 必须连接支持同一媒体的引脚。 REGPINMEDIUM 结构等效于用于内核流式处理驱动程序的 KSPIN_MEDIUM 结构,它定义了 DirectShow 中的媒体。 REGPINMEDIUM 结构的 clsMedium 成员指定介质的类标识符 (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.)
}
相关主题