在 64 位 AVStream 驱动程序中支持 DMA

AVStream 支持 32 位和 64 位可寻址设备上的 DMA。

为 Win64 平台编译的所有驱动程序都应使用 IKsDeviceFunctions::RegisterAdapterObjectEx 而不是 KsDeviceRegisterAdapterObject

IKsDeviceFunctions::RegisterAdapterObjectEx 仅在 Microsoft Windows Server 2003 SP1 及更高版本中可用。

以下代码示例演示如何在基于 x64 的客户端版本和 32 位平台上支持 DMA:

NTSTATUS MyDeviceStart (...) {
// Get the DMA adapter object and store it in the Context member of the I/O stack location.
Context -> AdapterObject = IoGetDmaAdapter (
Device -> PhysicalDeviceObject,
&DeviceDesc,
&Context -> NumberOfMapRegisters
);

PUNKNOWN DeviceUnk =
KsDeviceGetOuterUnknown (
Device
);

// Register the DMA adapter with AVStream
IKsDeviceFunctions *DeviceFunctions;
NTSTATUS Status = DeviceUnk -> QueryInterface (
__uuidof (IKsDeviceFunctions),
(PVOID *)&DeviceFunctions
);

// Conditionally, call IksDeviceFunctions::RegisterAdapterObjectEx, 
// which will not break downlevel load compatibility.

if (NT_SUCCESS (Status)) {
DeviceFunctions -> RegisterAdapterObjectEx (
Context -> AdapterObject,
&DeviceDesc,
Context -> NumMapRegisters,
MAX_MAPPING,
sizeof (KSMAPPING)
);
DeviceFunctions -> Release ();
}

// If this call fails, call KsDeviceRegisterAdapterObject to
// preserve downlevel load compatibility.
else {
KsDeviceRegisterAdapterObject (
Device,
Context -> AdapterObject,
MAX_MAPPING,
sizeof (KSMAPPING)
);
}
...

此代码示例适用于 64 位和 32 位平台。 如果驱动程序找不到 IKsDeviceFunctions::RegisterAdapterObjectEx,它仍调用 KsDeviceRegisterAdapter

此外,在创作 64 位 AVStream 驱动程序时,请尽量减少持有的并发帧锁数。 由于 AVStream 在微型驱动程序首次锁定帧时生成散点/收集映射,因此如果不遵循此准则,驱动程序可能会耗尽资源。 特别是,如果要编写驱动程序以在具有 32 位卡的 Win64 平台上运行,则增加同时锁的数量会增加锁失败的可能性,因为内存缓冲区不足是有限的资源。