转载请标明是引用于
http://blog.csdn.net/chenyujing1234
BSP SubProject 代码:
http://www.rayfile.com/zh-cn/files/3e467cab-8de6-11e1-a3c9-0015c55db73d/
我的代码参考了:(将Windows Embedded CE 6.0 USB Camera Driver.msi文件解压后得到的\cpp .h文件组成工程)
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19512
参考文章了:
http://jazka.blog.51cto.com/809003/707027
学习Camera驱动的过程中,发现网上的资料较少,而且偏向于5.0版本的。在自己研究了一段时间后发现出现这种情况也比较正常。因为5.0以前的版本都是流接口驱动结构的,而6.0的Camera驱动则向DirectShow架构靠拢了很多,所以无法从应用程序的调用到底层的操作都看的很清楚,除非对DirectShow架构非常熟悉。
WinCE6.0
的
Camera
的驱动依然是流接口驱动,以
dll
的形式提供各种流接口
,
MDD/PDD
的分层驱动结构图如下:
应用层中包括两部分
DirectShow
和
DeviceManager
,一般应用程序就通过调用这两个接口来对
Camera
驱动进行操作。
Camera
驱动有两个流接口
CAM_XXX
和
PIN_XXX
,在软件中通过
3
种对象和
Camera
设备进行交互:
Adapter
、
Pin
、
Stream
。
Adapter
是
Camera
具体设备的抽象,对应于
CAM_XXX
的流接口,
Pin
是
DShow
捕获视频数据时使用的设备,
Stream
代表流过的数据。
DShow
操作
Camera
流接口驱动也是通过
CreateFile
,
DeviceIOControl
等
API
进行的,其中最主要的就是各种
IOControlCode
,对应于不同的属性,如能力、状态以及设置等。
CAM_IoControl
的控制码大多数是
IOCTL_CS_PROPERTY
,数据缓冲也基本都是
CS PROPERTY
类似的结构,驱动通过这些数据读取应用程序提供的信息,判别操作的类型,调用
MDD
不同的处理函数完成。
PIN_IoControl
的控制码可能是
PROPERTY
、
BUFFERS
、
INSTANTIATE
,分别用来设置
Pin
、管理
Pin
的
Buffer
或者设置指定
Pin
的数据流的类型。
MDD
层
主要完成Sensor状态的控制、Video的处理和内存的管理。内存的管理如buffer是由驱动分配还是应用程序分配以及如何分配。MDD中只有一个API被PDD调用,就是MDD_HandleIO函数。
PDD
层
是对硬件功能的封装,主要包含以下七大类功能:
(1)
初始化函数:
PDD_Init
、
PDD_DeInit
;
(2)Camera
信息:PDD_GetAdapterInfo;
(3)
电源管理:
PDD_SetPowerState
;
(4)
内存管理:
PDD_AllocateBuffer
、
PDD_DeAllocateBuffer
、
PDD_RegisterClientBuffer
、
PDD_UnRegisterClientBuffer
;
(5)Sensor
管理:
PDD_GetSensorModeInfo
、
PDD_SetSensorModeFormat
、
PDD_InitSensorMode
、;
PDD_DeInitSensorMode
、
PDD_SetSensorState
;
(6)
数据捕获:
PDD_TakeStillPicture
、
PDD_FillBuffer
;
(7)
属性管理:
PDD_HandleVidProcAmpChanges
、
PDD_HandleCamControlChanges
、
PDD_HandleViedoControlCapsChanges
;
Camera
驱动的加载和调用过程大致如下
:
(1)device.exe
根据注册表信息加载
Camera
驱动,调用
CAM_Init
;
(2)CAM_Init
调用
PDD_Init
和
PDD_GetAdapterInfo
,完成硬件的初始化,返回
Camera
能力的一些信息,如支持的
Pin
的个数、对电源状态的支持和
Sensor
的属性,此时加载完成;
(3)FindFirstDevice
找到设备名称,如
CAM1;
(4)
通过
CreateFile
打开
CAM1
设备;
(5)
调用
DeviceIoControl
查找
Pin
的个数
(Pin
分为
Preview
预览、
Still
静态捕获、
Capture
视频捕获
)
;
(6)
获得
Pin
的个数等信息之后,通过
CreateFile
操作
PIN1
设备,对每个
Pin
进行初始化、分配内存;
(7)
用户选择预览、拍照、录像等操作,都会选择一个相应的
Pin
进行传递数据。传数据之前通过
IOControl StreamInstance
将准备好的
MsgQueue
的句柄传递给
Pin
,
MsgQueue
将用来在
DShow
和驱动之间进行异步传递数据,这些数据包括标记装载实际图像数据的缓冲。在
IOControl
完成之后,根据当前是预览、拍照还是录像的不同状态,调用
PDD
里面的
Sensor
管理函数或者数据捕获函数来控制
Camera
的状态,进行视频的捕获。
(8)在DShow当中,一个Pin的状态通常包括RUN、STOP、PAUSE三种,这些状态之间的切换是:RUNà PAUSEà STOPà PAUSEà RUN。
最后转载
MSDN
里面关于
DirectShow
结构的
Camera
驱动的初始化过程:
Initialization Sequence for Camera Drivers
camera设备的初始化序列是如下:
1、所有的Camera必须被注册到同样的GUID。
以下注册表显示一个camera驱动的流接口设备注册表入口
- [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\CameraDriver]
- "Prefix"="<Driver prefix>"
- "Dll"="<Driver DLL name>"
- "Order"=dword:10
- "Index"=dword:1
- "IClass"=multi_sz: "{CB998A05-122C-4166-846A-933E4D7E3C86}"
2、WCE设备管理器加载Camera设备并调用驱动的入口点,CAM_Init..
一旦接收到调用,camera设备驱动检测并初始化硬件,允许并初始化它的数据结构体并返回设备实例标识符。
此设备标识符将在CAM_Open 中被用.
3、DirectShow用适当的设备名调用CreateFile.
应用程序应该用FindFirstDevice来接收基于适当设备类GUID的真实的名字。
4、DirectShow用CSPROPERTY_PIN_CTYPES查询Camera驱动,以获得它支持的pin数量.
也可以用CSPROENTRY_PIN_CATEGORY查询类型 (预览、捕获、静止图片)
5、DirectShow用CSPROPERTY_PIN_DEVICENAME查询Camera驱动, 以获得pin设备的名字。
这个名字通常是PIN1:。但是驱动也有可能用其它名字。
6、DirectShow为每个Pin类型在PIN驱动上调用CreateFile
7、驱动通过设置它的特性和数据格式初始化流,并为它分配buffers
8、客户端用IOCTL_STREAM_INSTANTIATE(传递进来pin标识符和消息队列的句柄,此句柄用于在驱动和Direct中间层传递异步包)为给出的pin句柄设置流类型
比如,如果CSPROPERTY_PIN_CTYPES返回3,且如果CSPROPERTY_PIN_CATEGORY(假如Id = 0)返回PINNAME_VIDEO_PREVIEW,
之后它调用IOCTL_STREAM_INSTANTIATE(用Id = 0)把给定的句柄绑定到流中.
9、通过Pin开始流数据