Step 1: Learn about Windows architecture and drivers
AVStream:
AVStream is a Microsoft-provided multimedia class driver that supportsvideo-only streaming and integrated audio/video streaming. Microsoft providesAVStream as part of the operating system, in the export driver Ks.sys.Hardware vendors write minidrivers that run under Ks.sys.
The preferred class driver for audio drivers is the Microsoft-providedaudio port class driver. Audio vendors should write minidrivers that run under Portcls.sys.
Microsoft supports the stream class driver only for existing minidrivers.
AVStream drivers build on Microsoft Windows XP, Microsoft WindowsServer 2003, or any platform Windows 98 Gold or later version thathas DirectX 8.0 or later version installed.
If you build on an operating system earlier than Windows XP, make surethat you use the latest available DirectX Driver Development Kit (DDK). DirectX9.0 contains updates for AVStream, kernel streaming components, and streamclass.
AVStream offers significant advantages to the vendor by:
In the AVStream driver model, vendors provide a minidriver that interactswith a Microsoft-provided class driver, as shown in the following diagram:
Relationship Between AVStream and KS Services
All kernel streaming andAVStream reference material covers structures and functions that are declaredin ks.h. This is the header that the minidriver must include in order toaccess the Microsoft-supplied KS and AVStream class driver support.
An AVStream minidriver describes itself and the filter types itsupports by providing nested descriptor structures in the call toKsInitializeDriver. Each key component — the device, the filter factory, andthe pin factory — has an associated descriptor.
As shown in AVStream Object Hierarchy, the highest leveldescriptor for an AVStream minidriver is the device descriptor,KSDEVICE_DESCRIPTOR.
In the device descriptor, the FilterDescriptors member points toan array of KSFILTER_DESCRIPTOR structures that describe the types of filtersthis device can create. AVStream clients can call KsCreateFilterFactory todynamically add filter factories.
A KSFILTER_DESCRIPTOR indicates how many pin types the filtersupports, the KS categories under which the filter is to be registered, and thetopology of the filter. Inside each filter descriptor, the minidriver providesa pointer to an array of KSPIN_DESCRIPTOR_EX structures. Each of these pindescriptors describes a pin type that this filter can instantiate. You cancreate additional pin factories by calling KsFilterCreatePinFactory.
Typically, AVStream minidrivers lay out static descriptor tablesin their source and call KsInitializeDriver to perform the setup work. For moreinformation about initializing your driver, see Initializing an AVStreamMinidriver.
There are other types of descriptors as well, such as the nodedescriptor KSNODE_DESCRIPTOR, which describes a given topology node.
The dispatch table is common to each of the three maindescriptor types. See AVStream Dispatch Tables.
The AVStream dispatch table, KSDEVICE_DISPATCH,is a set of function pointers to dispatch functions. A minidriver can extendthe behavior provided by AVStream by providing callback routines that performdriver-specific tasks.
These minidriver-provided routines receive notifications ofcertain events and may extend or modify the default event handling provided byAVStream.
Both KSFILTER_DISPATCHand KSPIN_DISPATCHstructures provide a dispatch called Process. Use this dispatch todifferentiate a filter-centricfilter from a pin-centricfilter.To specify a filter-centric filter, supply a pointer to a processdispatch callback routine in the filter dispatch table. A pin-centric filterprovides a process dispatch in each of the pin descriptor tables.
You can register filters to be notified about creations,deletions, the need to process data, and resets. You can register pins to benotified of events such as creations, closure, the need to process data,resets, setting of data formats, and state changes. To register objects fornotification, supply a pointer to a vendor-supplied dispatch routine in therelevant dispatch structure.
For more information about dispatch functions, see KSFILTER_DISPATCH,KSPIN_DISPATCH,and KSALLOCATOR_DISPATCH.
Initializing an AVStream Minidriver
An AVStream minidriver that does not handle device initialization on itsown calls KsInitializeDriver from theminidriver's DriverEntry routine. KsInitializeDriverinitializes the driver object of an AVStream driver, in addition to IRPdispatching, PnP add device messages, and unloading.
In calling KsInitializeDriver, the minidriver passes a pointer tothe driver object to initialize a pointer to the registry path, and optionally,a device descriptor object. Note that passing the KSDEVICE_DESCRIPTOR object isnot required. If the minidriver does pass a device descriptor, AVStream createsa device with the specified characteristics at AddDevice time.
The device descriptor object contains a pointer to a KSDEVICE_DISPATCH structure as wellas an array of filter descriptors. Provide a KSFILTER_DESCRIPTOR for eachfilter type that your minidriver supports. When the minidriver calls KsInitializeDriver, AVStreamcreates a filter factory object for each type of filter exposed by theminidriver. Individual filters are then instantiated by the filter factory uponreceipt of a create IRP for the associated create item. Each filter descriptorcontains a pointer to an array of KSPIN_DESCRIPTOR_EX objects.AVStream creates a pin factory on the relevant filter for each type of pin theminidriver exposes through that filter.
When a connection is made to a given pi n type on a filter, the AVStreampin factory creates a pin object. Note that each filter must expose at leastone pin. The minidriver uses the InstancesNecessary member ofKSPIN_DESCRIPTOR_EX to identify the number of instances of this pin type thatare necessary for the filter to function correctly. Similarly, the minidrivercan impose a maximum on the number of pins that the pin factory can instantiateby using the InstancesPossible member of this structure.
AVStream supports two types of processing: filter-centric processing, and pin-centric processing. Whenlaying out the descriptors, decide which type of processing each filter typewill perform.
Installing an AVStream Minidriver
An AVStream minidriver must have an INF file that the system uses toinstall the driver. An AVStream INF file is based on the common INF format,which is described in Creating an INF File. You canalso refer to the INF files supplied with AVStream sample drivers in the WindowsDriver Kit (WDK). Keep in mind the following AVStream-specific guidelines.
If you are writing a minidriver for a parent device, the AddRegsection of your INF file should contain:
[ParentName.AddReg]
HKR,"ENUM\[DeviceName]",pnpid,,"[string]"
If you are writing a minidriver for a child device, the AddRegsection should contain:
[Manufacturer]
...=ChildName
[ChildName]
...=ChildName.Device,AVStream\[string]
Note that "AVStream" would be "Stream" for a streamclass driver.
For all AVStream minidrivers, the filter-specific reference string in theINF file must match the ReferenceGuid member of the KSFILTER_DESCRIPTOR structure.
For more information about descriptors, see AVStream Descriptors.
Pin-Centric Processing
When writing an AVStream minidriver, you provide filters that use one oftwo processing paradigms: pin-centric processing or filter-centric processing.
Pin-centric processing means that AVStream calls the minidriver's pinprocess dispatch routine when new frames arrive in the pin queue.
Filter-centric processing means that AVStream calls the minidriver'sfilter process dispatch routine when there are data frames available on eachinstantiated pin. Note that these definitions specify default behavior;minidrivers can modify the default behavior by setting flags in the KSPIN_DESCRIPTOR_EX structure.
In general, software filters use filter-centric processing and hardwarefilters use pin-centric processing. For instance, hardware that transforms orrenders data could route data on a pin-centric filter. There are rare cases inwhich these roles may be reversed.
To supply a pin-centric filter, the minidriver provides a pointer to an AVStrMiniPinProcesscallback routine in each KSPIN_DISPATCH structure; do notsupply a processing dispatch in the KSFILTER_DISPATCH structure.
If the minidriver does not modify flag settings in the KSPIN_DESCRIPTOR_EXstructure, AVStream calls the vendor-supplied AVStrMiniPinProcess callback routine in three situations:
By default, pause is the minimum processing state.
In addition, AVStream does not call the pin process dispatch if the pin'sAND gate is closed. If you use the KsGateXxx routines to addadditional off inputs to the pin's AND gate, for instance, your processdispatch will not be called.
When AVStream calls AVStrMiniPinProcess, it provides a pointer tothe pin object that has available data. The minidriver's processing dispatchcan then acquire a leading edge pointer by callingKsPinGetLeadingEdgeStreamPointer. Minidrivers then manipulate stream data using the stream pointer API.
Minidrivers that use pin-centric processing can modify when AVStream callsthe AVStrMiniPinProcess dispatch by setting flags in the relevant KSPIN_DESCRIPTOR_EX structure.Flag descriptions on the KSPIN_DESCRIPTOR_EX reference page are particularlyrelevant to vendors who are implementing pin-centric filters.
Processing attempts may fail if the minidriver is holding the processing mutex through KsPinAcquireProcessingMutex. Problems may also arise if the minidriver directly manipulates a gate byusing the KsGate* calls.
The Avshws sample in the Windows Driver Kit (WDK) is a pin-centriccapture driver for a simulated piece of hardware. The Avshws sampleshows how to implement DMA through AVStream.
Filter-Centric Processing
If a filter uses filter-centric processing, then by default AVStream callsthe minidriver-supplied AVStrMiniFilterProcess callback routine when there are data frames available on each pininstance. Minidrivers can modify this default behavior by setting the Flagsmember of the KSPIN_DESCRIPTOR_EX structure.
To implement filter-centric processing, provide a pointer to aminidriver-supplied AVStrMiniFilterProcess callback routine in the Process member of the KSFILTER_DISPATCH structure. Setthe Process member of KSPIN_DISPATCH to NULL.
AVStream calls AVStrMiniFilterProcess only when all of the following conditions are met:
In the AVStrMiniFilterProcess callback routine, the minidriver receives a pointer to an array of KSPROCESSPIN_INDEXENTRY structures. AVStream orders the array of KSPROCESSPIN_INDEXENTRYstructures by pin ID.
The following code examples illustrate how to use the process pin structures.The code is taken from the Avssamp sample, which demonstrates how towrite a filter-centric capture driver. Source code for this sample is includedin the Windows Driver Kit (WDK). The code is located in a subdirectory of thedirectory tree that contains WDK samples.
The minidriver receives an array of KSPROCESSPIN_INDEXENTRY structures inits filter process dispatch. In this example, the minidriver extracts the firstKSPROCESSPIN structure from the KSPROCESSPIN_INDEXENTRY structure of indexVIDEO_PIN_ID:
NTSTATUS
CCaptureFilter::
Process (
IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex
)
{
PKSPROCESSPIN VideoPin = NULL;
...
VideoPin = ProcessPinsIndex [VIDEO_PIN_ID].Pins [0];
...
}
The minidriver should not reference ProcessPinsIndex [n].Pins[0] before it has verified that the Count member of ProcessPinsIndex[n] is at least one, or that the InstancesNecessary memberof the KSPIN_DESCRIPTOR_EX structure contained within Pins [0] is atleast one. (If the latter is true, the pin is guaranteed to exist.)
Then, to specify the pin on which to capture frames, the AVStrMiniFilterProcess callback routine passes a pointer to a KSPROCESSPIN structure to CaptureFrame,a vendor-supplied capture routine:
VidCapPin -> CaptureFrame (VideoPin, m_Tick);
The capture routine can then copy to or from the Data member of theKSPROCESSPIN structure. It might also update the BytesUsed and Terminatemembers of this structure, as in the following example:
RtlCopyMemory ( ProcessPin -> Data,
m_SynthesisBuffer,
m_VideoInfoHeader -> bmiHeader.biSizeImage
);
ProcessPin -> BytesUsed = m_VideoInfoHeader -> bmiHeader.biSizeImage;
ProcessPin -> Terminate = TRUE;
The minidriver can also access the stream header structure correspondingto the current stream pointer and pin:
PKSSTREAM_HEADER StreamHeader = ProcessPin -> StreamPointer -> StreamHeader;
Most minidrivers that use filter-centric processing use the stream pointeronly for stream header access. In the filter-centric model, AVStreammanipulates the stream pointer internally. As a result, minidrivers shouldproceed with caution if they manipulate the stream pointer in a filter-centricdriver.
AVStream filters and pins describe properties, events, andmethods that they support by supplying a KSAUTOMATION_TABLEstructure in the AutomationTable member of either a KSFILTER_DESCRIPTORstructure or a KSPIN_DESCRIPTOR_EXstructure. For more information, see AVStreamDescriptors.
To support events, an AVStream minidriver provides an arrayof KSEVENT_SETstructures in an automation table. Each KSEVENT_SET structure contains an arrayof KSEVENT_ITEMstructures. Each KSEVENT_ITEM structure describes how the minidriver supports aspecific event.
The minidriver can customize event behavior by supplying AVStrMiniAddEventand AVStrMiniRemoveEventhandlers in the KSEVENT_ITEM structures.
When AVStream receives an event enable request, itgenerates a KSEVENT_ENTRY structure. If the minidriver has provided an AVStrAddEventhandler, AVStream passes a pointer to the KSEVENT_ENTRY structure in the callto AVStrAddEvent.
If you do not provide an AVStrAddEvent handler, thenby default AVStream adds the event to the object list. Your minidriver does notreceive a KSEVENT_ENTRYpointer. Your minidriver can trigger the event by calling KsFilterGenerateEventsor KsPinGenerateEvents.
This section applies to Microsoft Windows Server 2003 and earlieroperating systems only if DirectX 9.0 or later is installed on that platform.
AVStream can function as a bus enumerator for your device,creating a child device for each key in the Enum branch. To do this,place an Enum branch in the registry under the device key.
Specifically, in the AddReg section of the driver'sINF file, the vendor supplies a value pnpid of type REG_SZ for eachentry under Enum. AVStream uses this string value to construct a Plugand Play (PnP) hardware ID for each individual child device.
In releases earlier than DirectX 9.0, AVStream creates achild device hardware ID of the form "AVStream\
For example, the vendor specifies the following in the AddRegsection of the INF file:
[MyTVDevice.AddReg]
HKR,"ENUM\CrossbarDevice",pnpid,,"MyCrossbar"
HKR,"ENUM\TunerDevice",pnpid,,"MyTuner"
Accordingly, AVStream creates two child devices with thefollowing device IDs:
AVStream\MyCrossbar
AVStream\MyTuner
To resolve possible ambiguity from two different childdevices specifying the same pnpid value, DirectX 9.0 and later changethe IDs reported for each of the child devices. For each hardware ID reportedby the parent device, AVStream creates an ID for the child device in thefollowing form:
AVStream\
The modified parent hardware ID is the parent hardware IDwith each backslash (\) character replaced by the number sign (#).
If the resulting string is too long, AVStream terminatesthe ID string at MAX_DEVICE_ID_LEN characters, including the NULL terminator.In Windows Server 2003, this limit is set to 200 characters in cfgmgr32.h.
For example, a parent device reports the following hardwareIDs:
PCI\VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ&REV_VV
PCI\VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ
For a device with a pnpid key of MyCrossbar,AVStream creates the following child device hardware IDs:
AVStream\MyCrossbar#PCI#VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ&REV_VV
AVStream\MyCrossbar#PCI#VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ
AVStream uses the same process for compatible IDs reportedby the parent device. AVStream creates a compatible ID for the child device ofthe form:
AVStream\
The name modification and length rules for compatible IDsare identical to those for hardware IDs.
For example, if the parent device previously describedreports the following compatible IDs:
PCI\VEN_XXXX&DEV_YYYY&REV_VV
PCI\VEN_XXXX&DEV_YYYY
PCI\VEN_XXXX&CC_ZZZZZZ
PCI\VEN_XXXX&CC_ZZZZ
PCI\VEN_XXXX
PCI\CC_ZZZZZZ
PCI\CC_ZZZZ
The MyCrossbar child device would report throughAVStream the following compatible IDs:
AVStream\MyCrossbar#PCI#VEN_XXXX&DEV_YYYY&REV_VV
AVStream\MyCrossbar#PCI#VEN_XXXX&DEV_YYYY
AVStream\MyCrossbar#PCI#VEN_XXXX&CC_ZZZZZZ
AVStream\MyCrossbar#PCI#VEN_XXXX&CC_ZZZZ
AVStream\MyCrossbar#PCI#VEN_XXXX
AVStream\MyCrossbar#PCI#CC_ZZZZZZ
AVStream\MyCrossbar#PCI#CC_ZZZZ
AVStream\MyCrossbar
Note: InDirectX 9.0 and later, the legacy hardware ID, AVStream\
However, as of the DirectX 9.0 release,Microsoft recommends that vendors writingnew or revised drivers thatleverage the AVStream class bus enumerator use the new hardware ID formats.Drivers can support platforms running earlier versions of AVStream by includingthe old ID in the compatible IDs list in the INF file.
Restarting Processing in AVStream
AVStream stops processing if any of the following conditions are true:
AVStream initiates processing when new data arrives into a previouslyempty queue. Therefore, if the minidriver's processing dispatch returnsSTATUS_PENDING when the associated queues are full, the minidriver will neverbe called on to resume processing. If the minidriver sets STATUS_PENDING, theminidriver must call KsPinAttemptProcessing or KsFilterAttemptProcessing to resume processing.
Do not return STATUS_SUCCESS from the processing dispatch if theminidriver does not actually process data. This causes AVStream to immediatelycall the minidriver again, resulting in an infinite loop between AVStream andthe processing dispatch.
In the Windows Server 2008 WDK, five tools are provided inthe WDKPath\tools\avstream folder hierarchy. This topic explains thepurpose and basic usage of each tool. In some cases, additional documentationis included in the folder hierarchy.
AMCap2.exe (Active MovieCapture) is an application for enumerating and using audio and video capturedevices with the Microsoft DirectShow application programming interface.
AMCap2 includes one binary component: AMCap2.exe.
AMCap2 binaries are provided for x86-based and x64-basedarchitectures. AMCap2 runs on Microsoft Windows 2000, XP, Windows 2003 Server,and Vista.
When AMCap2 initializes, it enumerates available audio andvideo capture devices on its device menu. You can select none or one audioand/or video device. On the Settings menu, you can select specific device attributes.
For more information about DirectShow, see the DirectShowdocumentation on MSDN.
The AMCap2.exe tool has been removed from theWindows 7 WDK for both x86-based and x64-based platforms.
All the functionality of AMCap2 is still available in theexisting GraphEdt tool, which is included in the Windows 7 WDK.
GraphEdt.exe is adevelopment tool for visually building functional multimedia filter graphsusing the DirectShow application programming interface.
GraphEdt includes three binary components: GraphEdt.exe(the application), GraphEdt.chm (the help documentation), and Proppage.dll(a helper filter). Proppage.dll exposes additional property settings forfilters when registered with the operating system using the command"regsvr32 proppage.dll". The regsvr32 command must be run at elevatedprivilege level.
GraphEdt binaries are provided for x86-based and x64-basedarchitectures. GraphEdt runs on Microsoft Windows 2000, XP, Windows 2003Server, and Vista.
KsStudio.exe (KernelStreaming Development Studio) is a development tool used to examine multimediadriver properties, pins, and supported media.
KsStudio binaries are provided for Microsoft Windows Vistaon the x86-based and x64-based architectures. There is a version for Windows XPand Windows 2003 Server in the XP folder (for both x86 and x64). For Vista, thebinaries are KsStudio.exe (the application), KsStudio.chm (thehelp documentation), and KsMon.sys (a helper device driver). For XP andWindows 2003 Server, there is also SndAnlyz.dll (a helper file).
KsStudio is a kernel development tool, and therefore shouldbe used carefully. KsStudio.exe must write a summary log to the startingdirectory, which must have write access for the user. KsStudio attempts to loadits helper driver KsMon.sys. This loading is optional and will onlysucceed if KsMon.sys is in the starting directory and the command is runat elevated privilege level. Typically, KsStudio will present a dialog boxtitled "KS Studio Filter Options," which allows the user to specifyparameters, the most important of which are the Classes to enumerate. Use the Classesbutton on that dialog box to select none, any, or all classes.
This is a complex, yet elegant, and very handy developmenttool for multimedia device authors. For more information, refer to the KsStudio.chmhelp file.
MCStream.exe (MultiChannelStreaming Tool) is a development tool that allows the user to generate andrender multiple channel wave tones. MCStream is an older tool that uses KSdirectly, instead of DirectShow or Media Foundation.
Note MCStreamdoes not work with all audio renderers.
MCStream includes two binary components: MCStream.exe(the application) and MCStream.txt (the help documentation).
MCStream binaries are provided for x86-based and x64-basedarchitectures. MCStream runs on Microsoft Windows 2000, XP, Windows 2003Server, and Vista.
The MCstream.exe tool is not included in theWindows 7 WDK for both x86-based and x64-based platforms.
This tool uses legacy technology that is no longerrecommended for driver development in Windows 7 and later operatingsystems.
UVCView.exe (USB Video Classdescriptor viewer) is a development tool that allows the user to examine thedescriptors on any attached USB device. UVCView is a variation on USBView,which ships in this Windows Driver Kit (WDK) as a sample in the USB section.UVCView adds descriptive descriptor information for multimedia USB Audio andVideo Class devices.
UVCView includes one binary component: UVCView.exe.In the Windows Server 2008 WDK, this executable is located in the tools\avstreamfolder hierarchy. For documentation, see the USBView sample in WDKPath\src\usb\usbview.
UVCView binaries are provided for x86-based and x64-basedarchitectures. UVCView runs on Microsoft Windows 2000, XP, Windows 2003 Server,and Vista.
This section describes how to create video captureminidrivers, which follow the Windows Driver Model (WDM) architecture. Itassumes familiarity with concepts discussed in KernelStreaming. For information on creating a minidriver for audio-only devices,the Audiodevices Design Guide.
With the integration of DVD, MPEG decoders, video decodersand tuners, video port extensions (VPEs), and audio codecs on single adapters,a unified driver model that supports all these devices and handles resourcecontention simplifies development efforts.
The AVStreamand Streamclass interfaces both provide a framework that provide support forintegrated devices. These interfaces support data transfer between kernel-modedrivers. These data transfers do not require a thread to transition to usermode, thereby avoiding a performance hit.
Both interfaces support a uniform streaming model forstandard and custom data types. Microsoft defines property sets for moststandard devices. Vendors can provide additional property sets if needed.
Microsoft recommends that all new video capture drivers usethe AVStream interface. Microsoft provides the Stream class interface forbackwards compatibility. However, the Stream class interface is obsolete, andMicrosoft has discontinued its further development.
Note: Thissection does not describe the obsolete Video for Windows (VfW) technology. VfWwas optimized for capturing movies to disk. Features important to videoconferencing, TV viewing, capture of video fields, and ancillary data streamsare missing from the VfW architecture. To circumvent these limitations, vendorshave added proprietary extensions to VfW. However, without standardizedinterfaces, applications that use these features must includehardware-dependent code.
To bridge the VfW and WDM driver models,Microsoft provides a VfW-to-WDM mapper as part of the operating system. Thiscomponent enables WDM drivers to appear as VfW drivers for legacy VfWapplications.
This section includes:
VideoCapture Overview
ImplementingVideo Capture Support
For more information about WDM video capture driverdevelopment, see the videocapture technologies Web site.
Video Capture Overview
Video capture minidrivers interact with either the AVStream of Streamclass interfaces to control hardware devices that primarily produce streams ofvideo data, along with ancillary data such as TV audio, or AM/FM tunerfunctionality. Vendors write a video capture minidriver to:
The following sections describe the general steps a Streamclass minidriver follows to implement video capture:
Registeringwith the Stream Class Interface
Selectinga Stream Format
Openingand Closing a Stream
StreamingStates
StateTransitions
CapturingVideo
Registering with the Stream Class Interface
Stream class minidrivers use the following steps to initialize and prepareto stream data:
Video capture devices can capture video in a number ofdifferent formats. The KSDATARANGEstructure is used to convey information about the width, height, granularity,cropping, and frame rates for a particular color space. The structures KS_DATARANGE_VIDEOand KS_DATARANGE_VIDEO2are extensions of the KSDATARANGE structure and should be used for describingvideo capture formats. Use KS_DATARANGE_VIDEO to describe video frames only.Use KS_DATARANGE_VIDEO2 to describe video fields and video frames, with orwithout bob or weave settings.
The process of selecting a stream format is called performinga data intersection. The Stream class interface sends an SRB_GET_DATA_INTERSECTIONrequest to a Stream class minidriver to perform a data intersection. Theminidriver is responsible for determining the validity of the data rangerequested and then selecting a particular stream format from the supplied datarange, typically using KS_DATAFORMAT_VIDEOINFOHEADERor KS_DATAFORMAT_VIDEOINFOHEADER2structures.
Finally, the minidriver must set certain members of theresulting format as shown below:
.
.
.
// Calculate biSizeImage for this request, and put the result in both
// the biSizeImage field of the bmiHeader AND in the SampleSize field
// of the DataFormat.
//
// Note that for compressed sizes, this calculation will probably not
// be just width * height * bitdepth
DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader.biSizeImage =
DataFormatVideoInfoHeaderOut->DataFormat.SampleSize =
KS_DIBSIZE(DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader);
The Stream class interface sends an SRB_OPEN_STREAMrequest to a Stream class minidriver to open a stream with the selected videoformat. Information passed in SRB_OPEN_STREAM includes the index of the streamto be open and a pointer to a pointer to a KS_VIDEOINFOHEADERstructure. The stream index corresponds to the index of the stream in the arrayof KS_DATARANGE_VIDEOstructures returned by the minidriver in response to an earlier SRB_GET_STREAM_INFOrequest. For more information about handling SRB_GET_STREAM_INFO, see StreamCategories.
The following example code obtains the stream index, kernelstreaming data format, and kernel streaming video info header.
int StreamNumber = pSrb->StreamObject->StreamNumber;
PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat =
(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
&pKSDataFormat->VideoInfoHeader;
Minidrivers should verify that they can support therequested stream format. In particular, the contents of the KS_BITMAPINFOHEADERstructure should be verified, along with cropping and scaling informationspecified by the rcSource and rcTarget members.
If the device hardware cannot support the capture framerate requested in the AvgTimePerFrame member of KS_VIDEOINFOHEADER, itshould always select the next lower frame rate available. For example,if a camera can support a capture frame rate of 7 frames per second (fps) and15 fps, and a client application attempts to open the stream at a capture framerate of 10 fps, the camera should create a 7-fps physical stream.
For a ten-second capture in which all 70 available physicalframes are captured, the minidriver should report 100 frames captured, 30frames of which were dropped by the KSPROPERTY_DROPPEDFRAMES_CURRENTproperty.
Special rules apply when the output buffer is a DirectDrawsurface. In this case, the biWidth member of the KS_BITMAPINFOHEADERstructure actually represents the stride of the destination DirectDraw surface,which typically is larger than the video image width. The stride of a surfaceis usually the width of the surface multiplied by its byte-depth. For example,for a surface that is 640 pixels wide with a color depth of 32 bits-per-pixel,the stride would be 2560 bytes.
To determine the requested image width, use the followingcode example:
if (IsRectEmpty(&pVideoInfoHdrRequested->rcTarget) {
Width = pVideoInfoHdrRequested->bmiHeader.biWidth;
Height = pVideoInfoHdrRequested->bmiHeader.biHeight;
}
else {
Width = pVideoInfoHdrRequested->rcTarget.right −
pVideoInfoHdrRequested->rcTarget.left;
Height = pVideoInfoHdrRequested->rcTarget.bottom −
pVideoInfoHdrRequested->rcTarget.top;
}
The Stream class interface sends an SRB_CLOSE_STREAMrequest to the minidriver to close a stream. The minidriver should then returnall outstanding stream SRBs to the Stream class interface.
Streaming States
Each stream provided by the minidriver exists in one of four states:KSSTATE_STOP, KSSTATE_ACQUIRE, KSSTATE_PAUSE, or KSSTATE_RUN. Uponinitialization, the stream is, by default, in the KSSTATE_STOP state.Transitions to the other states are made when the Stream class interface sendsan SRB_SET_STREAM_STATE request tothe minidriver. The following table identifies and describes the four streamstates.
State |
Description |
KSSTATE_STOP |
When the stream state is stopped, the minidriver uses the absolute minimum of resources, and there are no outstanding data SRBs in the minidriver’s queue. |
KSSTATE_ACQUIRE |
When the stream state is acquiring resources, the minidriver allocates all needed resources, such as bandwidth on USB and IEEE 1394. |
KSSTATE_PAUSE |
When the stream state is paused, the minidriver is prepared to instantly make a transition to KSSTATE_RUN. |
KSSTATE_RUN |
When the stream state is streaming, the minidriver fills buffers and completes SRBs using CompleteStreamSRB. |
State Transitions
To ensure orderly resource allocation, only a subset of the possiblekernel streaming state transitions is allowed. The following table lists theallowed transitions along with tasks that a Stream class minidriver typicallyperforms during such transitions.
Transition |
Description |
Stop to pause |
Allocate resources. The read SRBs are queued after the transition to KSSTATE_PAUSE has completed. |
Pause to run |
Begin streaming. |
Run to pause |
Stop streaming. The outstanding read SRBs remain in the queue maintained by the minidriver. |
Pause to stop |
Deallocate resources and complete all outstanding read SRBs. SRBs that have not been filled with an image are completed with zero length in the DataUsed member of the KSSTREAM_HEADER structure. |
Note: Transitions can cycle multipletimes between the KSSTATE_PAUSE and KSSTATE_RUN states before returning to theKSSTATE_STOP state. Video capture minidrivers should expect transitions suchas:
KSSTATE_STOP -> KSSTATE_ACQUIRE -> KSSTATE_PAUSE -> KSSTATE_RUN-> KSSTATE_PAUSE -> KSSTATE_RUN -> KSSTATE_PAUSE -> KSSTATE_STOP
When a stream is in a KSSTATE_STOP state, the minidriver must immediatelycomplete all outstanding data-read SRBs.
Because a user-mode application can end unexpectedly while streaming, allStream class minidrivers must accept and process an SRB_CLOSE_STREAM request from theStream class interface at any time. Before the Stream class interface sends SRB_CLOSE_STREAMto a minidriver, it cancels all outstanding buffers through the minidriver’s HwCancelPacketroutine. Note that the stream state cannot be set to KSSTATE_STOP before theapplication terminates.
Do not update the PictureNumber or DropCount members of KS_FRAME_INFO, KS_VBI_FRAME_INFO, or KSPROPERTY_DROPPEDFRAMES_CURRENT_S on transition from KSSTATE_PAUSE to KSSTATE_RUN or KSSTATE_RUN toKSSTATE_PAUSE. For more information, see Capturing Video.
Once the stream is in the KSSTATE_RUN state, the captureprocess begins. Based on the frame interval specified by the AvgTimePerFramemember of the KS_VIDEOINFOHEADERstructure passed when the stream is opened, the stream transfers images intobuffers passed through SRB_READ_DATA. Additional information about the imagecaptured is returned in the KS_FRAME_INFOstructure that is appended to the end of the KSSTREAM_HEADERstructure.
The following example code obtains the appendedKS_FRAME_INFO structure:
PKSSTREAM_HEADER pDataPacket = pSrb->CommandData.DataBufferArray;
PKS_FRAME_INFO pFrameInfo = (PKS_FRAME_INFO) (pDataPacket + 1);
A minidriver should set additional information fields aboutthe data captured, such as frames captured, frames dropped, and field polarity.The frame information is generally stored in a member of the driver-writerdefined stream extension.
*pFrameInfo = pStrmEx->FrameInfo; // Get the frame info from the minidriver-defined stream extension
It is optimal to update the PictureNumber or DropCountmembers of KS_FRAME_INFO,KS_VBI_FRAME_INFO,or KSPROPERTY_DROPPEDFRAMES_CURRENT_Sat transition into the KSSTATE_ACQUIRE state.
It is acceptable to update these members on transition fromthe KSSTATE_ACQUIRE state into the KSSTATE_PAUSE state.
Do not update PictureNumber or DropCount ontransition from the KSSTATE_PAUSE state to the KSSTATE_RUN state or theKSSTATE_RUN state to the KSSTATE_PAUSE state.
If frames have been previously dropped, the minidrivershould set the discontinuity flag and then reset its internal flag. Thefollowing code demonstrates setting the data discontinuity flag:
if (pStrmEx->fDiscontinuity) {
pDataPacket->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY;
pStrmEx->fDiscontinuity = FALSE;
}
Finally, the minidriver should relinquish control of theSRB, completing the frame capture.
CompleteStreamSRB (pSrb);