Packet-based DMA in AVStream

Packet-based direct memory access (DMA) occurs when your minidriver reads data directly from and writes data directly to capture buffers received from user mode. The AVStream Simulated Hardware Sample Driver (AVSHwS) in the Windows Driver Kit (WDK) samples demonstrates how to build an AVStream minidriver that performs this type of DMA.

To implement a packet-based DMA scheme:

  1. Specify KSPIN_FLAG_GENERATE_MAPPINGS in the Flags member of relevant KSPIN_DESCRIPTOR_EX structures. Note that this flag should only be used by a bus master with scatter/gather support.

  2. Register an interrupt service routine (ISR) as described in Writing AVStream Minidrivers for Hardware.

Then in the AVStrMiniDeviceStart start dispatch:

  1. Set up a DMA adapter object using IoGetDmaAdapter.

  2. Register the DMA adapter object with AVStream by calling KsDeviceRegisterAdapterObject.

The minidriver specifies the maximum size for a single scatter/gather mapping by providing a MaxMappingByteCount parameter in the call to KsDeviceRegisterAdapterObject.

If any scatter/gather mapping exceeds this maximum size, AVStream automatically breaks the mapping into several scatter/gather mappings, each of which is no larger than the size specified in MaxMappingByteCount.

You must also provide an AVStrMiniPinProcess callback routine. The driver writer should choose appropriate functionality for this callback. As one example, you could do the following:

  1. Call KsPinGetLeadingEdgeStreamPointer.

  2. Clone the leading edge by calling KsStreamPointerClone.

  3. Program DMA hardware based on the clone.

  4. Call KsStreamPointerAdvanceOffsets or KsStreamPointerAdvance to advance the leading edge.

  5. Repeat from step 2 as needed for additional frames.

When the hardware interrupts for DMA completion, the kernel calls the ISR that the vendor has previously registered. In the ISR, the minidriver queues a deferred procedure call (DPC).

Your DPC should update DataUsed and possibly other members of the KSSTREAM_HEADER structure. The DPC might then call KsStreamPointerDelete to delete the clone and release the associated frame.

Alternatively, the DPC could advance the clone pointer if only part of the frame is completed. To do this, call KsStreamPointerAdvanceOffsets.

If necessary to resume processing, call KsPinAttemptProcessing.

Note

If a mapping is less than one physical page in length, it is not guaranteed to reside on a single physical page.