学习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
The initialization sequence for camera devices is as follows:
- All camera drivers must be registered under the same GUID. The following code shows the stream interface driver registry entry for a camera driver.
[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}"
- The Windows Embedded CE Device Manager loads the camera driver and calls the driver's entry point, CAM_Init. Upon receiving the call, the camera driver detects and initializes the hardware, allocates and initializes its data structures, and returns device instance identifier. This device identifier will be used in subsequent calls toCAM_Open.
- DirectShow calls CreateFile using the appropriate device name. Applications should useFindFirstDevice to retrieve the actual name based on the appropriate device class GUID.For more information, see Capture Device Selection.
- DirectShow queries the camera driver for the number of pins it supports usingCSPROPERTY_PIN_CTYPES (see CSPROPERTY_PIN). It then queries for the type (preview, capture, or still) of each of these pins using CSPROPERTY_PIN_CATEGORY.
- DirectShow queries the camera driver for the name of the pin device usingCSPROPERTY_PIN_DEVICENAME. This will commonly be PIN1:, but drivers are free to use whatever name they wish.
- DirectShow calls CreateFileon the pin driver for each pin type the camera driver supports.
- The driver initializes the stream by setting its properties and data formats and by allocating buffers for it.
- The client sets the stream type for the given pin handle using IOCTL_STREAM_INSTANTIATEby passing, as input, the identifier of the pin and a handle to the message queue that will be used for transferring asynchronous bundles between the driver and the DirectShow middleware. For example, if CSPROPERTY_PIN_CTYPES returned 3 and if theCSPROPERTY_PIN_CATEGORY for Id = 0 returned PINNAME_VIDEO_PREVIEW, then callingIOCTL_STREAM_INSTANTIATE with PinId = 0 would associate the given handle to preview stream.
- Begin streaming data through the pins
From the perspective of the camera driver, there are at least two objects to instantiate: one for the adapter and one for the stream. If the camera supports more than one stream then driver must instantiate additional pins.
The camera adapter entry points are referred to as CAM_XXX and stream entry points are referred to as PIN_XXX. For a complete list of entry point functions, see
Camera Driver Functions.