原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
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
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 to CAM_Open.
- DirectShow calls CreateFile using the appropriate device name. Applications should use FindFirstDevice 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 using CSPROPERTY_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 using CSPROPERTY_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 formatsand by allocating buffers for it.
- The client sets the stream type for the given pin handle using IOCTL_STREAM_INSTANTIATE by 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 the CSPROPERTY_PIN_CATEGORY for Id = 0 returned PINNAME_VIDEO_PREVIEW, then calling IOCTL_STREAM_INSTANTIATEwith 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.
本文出自 “飞雪待剑” 博客,请务必保留此出处http://jazka.blog.51cto.com/809003/707027