以筛选为中心的处理

如果筛选器使用以筛选方式为中心的处理,则默认情况下,AVStream 在每个 pin 实例上都有可用的数据帧时调用微型驱动程序提供的 AVStrMiniFilterProcess 回调例程。 微型驱动程序可以通过设置KSPIN_DESCRIPTOR_EX结构的Flags成员来修改此默认行为。

若要实现以筛选为中心的处理,请提供一个指针,指向KSFILTER_DISPATCH结构的进程成员中的微型驱动程序提供的AVStrMiniFilterProcess回调例程。 将KSPIN_DISPATCH进程成员设置为NULL

仅当满足以下所有条件时,AVStream 才会调用 AVStrMiniFilterProcess

  • 需要帧才能进行处理的 pin 上提供了帧。 微型驱动程序可以通过在KSPIN_DESCRIPTOR_EXflags成员中设置标志来修改处理行为。 请特别注意互斥标志 KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING 和 KSPIN_FLAG_SOME_FRAMES_REQUIRED_FOR_PROCESSING 的组合。 微型驱动程序还可以通过使用 KsPinAttachAndGateKsPinAttachOrGate 例程来修改需要帧的 pin 集。

  • Pin 实例数等于或大于KSPIN_DESCRIPTOR_EX结构的InstancesNecessary成员。 KSPIN结构的ClientState成员指定当前设置了 pin 的特定KSSTATE枚举器。 满足 InstancesNecessary 后,处于 KSSTATE_STOP 状态的其他 pin 不会阻止筛选器处理。

  • 满足KSPIN_DESCRIPTOR_EX结构的InstancesNecessary成员指定 (所需的 pin 实例数量。

  • 微型驱动程序尚未使用 KSGATEXxx 函数关闭筛选器的处理控制入口。

AVStrMiniFilterProcess 回调例程中,微型驱动程序接收指向 KSPROCESSPIN_INDEXENTRY 结构的数组的指针。 AVStream 按 pin ID 对 KSPROCESSPIN_INDEXENTRY 结构的数组进行排序。

下面的代码示例演示如何使用处理 pin 结构。 此代码取自 AVStream Filter-Centric 模拟捕获驱动程序 (Avssamp) 示例,该示例演示如何编写以筛选为中心的捕获驱动程序。 本示例的源代码和说明包括在 Windows 驱动程序工具包下载中。

微型驱动程序接收到其筛选器进程调度中 KSPROCESSPIN_INDEXENTRY 结构的数组。 在此示例中,微型驱动程序从索引 VIDEO_PIN_ID 的 KSPROCESSPIN_INDEXENTRY 结构中提取第一个 KSPROCESSPIN 结构:

NTSTATUS
CCaptureFilter::
Process (
    IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex
    )
{
PKSPROCESSPIN VideoPin = NULL;
...
VideoPin = ProcessPinsIndex [VIDEO_PIN_ID].Pins [0];
...
}

微型驱动程序不应引用ProcessPinsIndex [n]。在以下情况下,请先锁定[0],然后再验证ProcessPinsIndex [n] 的Count成员是否为至少一个,或者pin [0] 中包含的 KSPIN_DESCRIPTOR_EX 结构的InstancesNecessary成员是否至少为1。 (如果后者为 true,则保证 pin 存在。 )

然后,若要指定捕获帧的 pin, AVStrMiniFilterProcess 回调例程会将指向 KSPROCESSPIN 结构的指针传递到 CaptureFrame,即供应商提供的捕获例程:

VidCapPin -> CaptureFrame (VideoPin, m_Tick);

然后,捕获例程可以复制到 KSPROCESSPIN 结构的 数据 成员或从中复制数据。 它还可以更新 BytesUsed终止 此结构的成员,如以下示例中所示:

RtlCopyMemory ( ProcessPin -> Data,
                m_SynthesisBuffer,
                m_VideoInfoHeader -> bmiHeader.biSizeImage
               );
ProcessPin -> BytesUsed = m_VideoInfoHeader -> bmiHeader.biSizeImage;
ProcessPin -> Terminate = TRUE;

微型驱动程序还可以访问与当前流指针和 pin 对应的流标头结构:

PKSSTREAM_HEADER StreamHeader = ProcessPin -> StreamPointer -> StreamHeader;

使用以筛选器为中心的处理的大多数微型驱动程序只使用流指针进行流头访问。 在以筛选为中心的模型中,AVStream 在内部处理流指针。 因此,如果微型驱动程序在以筛选器为中心的驱动程序中操作流指针,则应小心操作。