WinXP下虚拟摄像头驱动程序开发

 WinXP下虚拟摄像头驱动程序开发

摄像头驱动程序的主要目的是通过硬件捕捉视频信号。微软公司提供了一套视频驱动的接口,可以满足这个接口的视频驱动程序。第三方厂商开发的软件,如QQMSN等软件,都可以通过这个接口读取视频摄像头采集的数据。本文将介绍一个虚拟摄像头的实现,读者可以根据自己的需要,结合硬件设计出符合这个接口的USB或者PCI摄像头驱动程序。

1               驱动框架

WinXP下采用WDM模式进行摄像头驱动程序开发主要包含两个部分,一部分时类驱动程序,一部分是小驱动程序。类驱动程序由微软提供,而小驱动程序是由程序自己编写,并实现相关扩展功能。

摄像头采集的数据都是纯粹的数据文件,然后源源不断地传递给PC机。因此得名Stream(流设备)。编写摄像头驱动程序就是编写流设备的小驱动,但首先需要了解类设备驱动与小驱动之间是如何配合的。在WDM驱动程序当中,小驱动需要首先将自己注册给类驱动,类驱动拥有真正的设备对象,然而小驱动程序不创建对象,它仅利用类驱动程序实现系统调用。

流设备的类驱动主要是控制请求。这需要通过调用小驱动的适配器来访问具体的硬件。在流设备的类驱动和小驱动都初始化以后,小驱动需要被动地等待类驱动来调用。类驱动用(stream request blockSRB向小驱动程序发送标准的请求,小驱动通过解析SRB后向Class Driver的请求。例如在SRB中,类驱动与小驱动采用数据结构HW_STREAM_REQUEST_BLOCK来传送命令和数据。

2               初始化

与其他驱动程序不同,类驱动与小驱动采用HW_INITIALIZATION_DATA数据结构进行初始化操作,其初始化步骤如下。

当设备接入插口时,即插即用管理器能够监测到新的设备,进而调用Mini DriverDriverEntry例程。

申请HW_INITIALIZATION_DATA数据内存,并填充相关域,调用StreamClassRegisterMinidriver函数注册该小驱动。如下代码;

RtlZeroMemory(&HwInitData, sizeof(HwInitData));

    HwInitData.HwInitializationDataSize = sizeof(HwInitData);

    //

    // Set the Adapter entry points for the driver

    //

    HwInitData.HwInterrupt               = NULL; // HwInterrupt;         

    HwInitData.HwReceivePacket          = AdapterReceivePacket;

    HwInitData.HwCancelPacket           = AdapterCancelPacket;

    HwInitData.HwRequestTimeoutHandler   = AdapterTimeoutPacket;

    HwInitData.DeviceExtensionSize        = sizeof(HW_DEVICE_EXTENSION);

    HwInitData.PerRequestExtensionSize     = sizeof(SRB_EXTENSION);

    HwInitData.FilterInstanceExtensionSize   = 0;

    HwInitData.PerStreamExtensionSize      = sizeof(STREAMEX);

    HwInitData.BusMasterDMA            = FALSE;

    HwInitData.Dma24BitAddresses         = FALSE;

    HwInitData.BufferAlignment          = 3;

    HwInitData.DmaBufferSize           = 0;

    // Don't rely on the stream class using raised IRQL to synchronize

    // execution.  This single paramter most affects the overall structure

    // of the driver.

    HwInitData.TurnOffSynchronization   = TRUE;

    ReturnValue = StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData);

AdapterReceivePacket函数用于接收类驱动向小驱动发送的SRB,其中SRB_INITIALIZE_DEVICE用于初始化小驱动,SRB_INITIALIZE_DEVICE结构体中ConfigInfo记录着摄像头的意见相关信息。初始化之后类驱动再向小驱动发送SRB_GET_STREAM_INFO类型的SRB,用于向小驱动程序咨询HW_STREAM_HEADER数据信息和HW_STREAM_INFORMATION等信息。这些信息包含了摄像头驱动提供的视频图像大小、图像格式等信息。最后类驱动程序小驱动再发送HW_STREAM_INFORMATIONSRB,这次请求之后,小驱动的初始化操作基本完成,并返回给类驱动程序。上述这些过程的代码如下;

switch (pSrb->Command)

{

case SRB_INITIALIZE_DEVICE:

// open the device

HwInitialize(pSrb);

break;

case SRB_UNINITIALIZE_DEVICE:

// close the device.

HwUnInitialize(pSrb);

break;

case SRB_OPEN_STREAM:

        // open a stream

AdapterOpenStream(pSrb);

break;

case SRB_CLOSE_STREAM:

// close a stream

AdapterCloseStream(pSrb);

break;

case SRB_GET_STREAM_INFO:

        AdapterStreamInfo(pSrb);

        break;

    case SRB_GET_DATA_INTERSECTION:

        AdapterFormatFromRange(pSrb);

break;

case SRB_OPEN_DEVICE_INSTANCE:

case SRB_CLOSE_DEVICE_INSTANCE:

 

        TRAP;

        pSrb->Status = STATUS_NOT_IMPLEMENTED;

        break;

    case SRB_GET_DEVICE_PROPERTY:

        AdapterGetProperty (pSrb);

        break;

    case SRB_SET_DEVICE_PROPERTY:

        AdapterSetProperty (pSrb);

        break;

case SRB_PAGING_OUT_DRIVER:

    DbgLogInfo(("'Testcap: Receiving SRB_PAGING_OUT_DRIVER -- SRB=%x/n", pSrb));

        break;

case SRB_CHANGE_POWER_STATE:

    DbgLogInfo(("'Testcap: Receiving SRB_CHANGE_POWER_STATE ------ SRB=%x/n", pSrb));

        AdapterPowerState(pSrb);

        break;

case SRB_INITIALIZATION_COMPLETE:

    DbgLogInfo(("'Testcap: Receiving SRB_INITIALIZATION_COMPLETE-- SRB=%x/n", pSrb));

        break;

case SRB_UNKNOWN_DEVICE_COMMAND:

default:

pSrb->Status = STATUS_NOT_IMPLEMENTED;

}

CompleteDeviceSRB (pSrb);

3               编写小驱动程序

类驱动程序的目标是与操作系统进行交互,其中包括处理同步、提供标准接口。而小驱动由类驱动调用,主要负责具体的硬件相关操作。因此编写小驱动的程序应该会向类驱动注册一些回调函数,方便类驱动调用。其中有几个函数是必须注册的,如下;

Ø         StrMiniCancelPacket:对HW_STREAM_REQUEST_BLOCK数据包进行取消的回调函数。

Ø         StrMiniReceieveDevicePacket:获取HW_STREAM_REQUEST_BLOCK数据包回调函数。

Ø         StrMiniRequestTimeout:当HW_STREAM_REQUEST_BLOCK数据包超时的回调函数。

Ø         StrMiniEvent:使小驱动程序支持某种事件。

Ø         StrMiniInterrupt:当驱动获取中断时还用该支持中断处理函数。

编写小驱动程序时,还需要注意实现流控制操作,流控制命令和数据主要保存在SRB当中,其中以下几种流控制命令必须实现。

Ø         SRB_INITIALIZE_DEVICE:调用HW_INITIALIZATION_DATA数据结构中初始化小驱动程序。

Ø         SRB_GET_STREAM_INFO:调用HW_INITIALIZATION_DATA数据结构中获取流相关信息。

Ø         SRB_OPEN_STREAM:打开一个流实例,并填充HW_STREAM_OBJECT结构体流描述信息。

Ø         SRB_READ_DATASRB_WRITE_DATA:这两个命令用于接收和发送数据。

Ø         HW_STREAM_REQUEST_BLOCK:类驱动为了获得或者设置小驱动的某项属性或者流的某项属性,会向小驱动提供HwReceivePacket函数发送HW_STREAM_OBJECT请求。

Ø         SRB_CLOSE_STREAM:用于关闭小驱动程序。

4               总结

  在微软提供的类驱动程序之上编写虚拟驱动程序,其实最主要的工作就是编写子驱动程序,实现初始化、流控制、数据接收等相关回调函数。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值