浅析OpenNI2---Driver开发(2)
来源:互联网 发布:程序员杂志 2016 pdf 编辑:程序博客网 时间:2024/06/08 09:46
上一篇文章,介绍了OpenNI2底层与OpenCore的交互API以及各个驱动加载的过程,这篇文章介绍下OpenNI2底层驱动的实现;
上文中我们了解到底层驱动需要实现三个类DriverBase、DeviceBase、StreamBase,下面分析下各个类包含的功能同时结合DummyDevice分析下具体流程;
DriverBase
DriverServices 用于记录log
DriverBase 用于管理Device,包括设备发现,设备状态上报,以及deviceOpen、deviceClose等操作;
在DummyDevice 中 OzDriver 有一个m_devices的成员,用于保存连接在系统的设备信息,deviceOpen时会遍历其中的元素匹配uri,然后创建device后返回给OpenCore;m_devices中元素是在tryDevice中加入的;tryDevice扮演着设备发现的角色,在有些实现中是通过线程来发现设备的。
// log recorderclass DriverServices{public: DriverServices(OniDriverServices* pDriverServices) : m_pDriverServices(pDriverServices) {} void errorLoggerAppend(const char* format, ...) void errorLoggerClear() void log(int severity, const char* file, int line, const char* mask, const char* message)private: OniDriverServices* m_pDriverServices;};class DriverBase{public: // 构造函数中传递记录log的DriverServices DriverBase(OniDriverServices* pDriverServices) : m_services(pDriverServices) {} virtual ~DriverBase() {} // 注册用于设备发现和状态上报的三个回调函数 virtual OniStatus initialize(DeviceConnectedCallback connectedCallback, DeviceDisconnectedCallback disconnectedCallback, DeviceStateChangedCallback deviceStateChangedCallback, void* pCookie) { m_deviceConnectedEvent = connectedCallback; m_deviceDisconnectedEvent = disconnectedCallback; m_deviceStateChangedEvent = deviceStateChangedCallback; m_pCookie = pCookie; return ONI_STATUS_OK; } // 设备打开和关闭操作 virtual DeviceBase* deviceOpen(const char* uri, const char* mode) = 0; virtual void deviceClose(DeviceBase* pDevice) = 0; virtual void shutdown() = 0; virtual OniStatus tryDevice(const char* /*uri*/) { return ONI_STATUS_ERROR;}protected: void deviceConnected(const OniDeviceInfo* pInfo) { (m_deviceConnectedEvent)(pInfo, m_pCookie); } void deviceDisconnected(const OniDeviceInfo* pInfo) { (m_deviceDisconnectedEvent)(pInfo, m_pCookie); } void deviceStateChanged(const OniDeviceInfo* pInfo, int errorState) { (m_deviceStateChangedEvent)(pInfo, errorState, m_pCookie); } DriverServices& getServices() { return m_services; }private: // 回调函数句柄 DeviceConnectedCallback m_deviceConnectedEvent; DeviceDisconnectedCallback m_deviceDisconnectedEvent; DeviceStateChangedCallback m_deviceStateChangedEvent; void* m_pCookie; DriverServices m_services;};}} // oni::driverclass OzDriver : public oni::driver::DriverBase{public: virtual oni::driver::DeviceBase* deviceOpen(const char* uri, const char* /*mode*/) { // 遍历m_devices中的元素 for (xnl::Hash<OniDeviceInfo*, oni::driver::DeviceBase*>::Iterator iter = m_devices.Begin(); iter != m_devices.End(); ++iter) { if (xnOSStrCmp(iter->Key()->uri, uri) == 0) { // Found if (iter->Value() != NULL) { // already using return iter->Value(); } // 创建device OzDevice* pDevice = XN_NEW(OzDevice, iter->Key(), getServices()); iter->Value() = pDevice; return pDevice; } } return NULL; } virtual OniStatus tryDevice(const char* uri) { if (xnOSStrCmp(uri, "Dummy") != 0 && xnOSStrCmp(uri, "Oz") != 0 && xnOSStrCmp(uri, "PingPong") != 0) { return ONI_STATUS_ERROR; } // 创建设备信息 OniDeviceInfo* pInfo = XN_NEW(OniDeviceInfo); xnOSStrCopy(pInfo->uri, uri, ONI_MAX_STR); xnOSStrCopy(pInfo->vendor, "Table Tennis", ONI_MAX_STR); m_devices[pInfo] = NULL; // 通知OpenCore 发现有设备连接 deviceConnected(pInfo); return ONI_STATUS_OK; } XN_THREAD_HANDLE m_threadHandle; xnl::Hash<OniDeviceInfo*, oni::driver::DeviceBase*> m_devices;};
DeviceBase
DeviceBase由DriverBase 创建出来的,其标志一个真实的RGBD设备;包含该设备中的sensor信息,同时提供createStream来根据sensorType创建StreamBase;
在DummyDevice 中 OzDevice 类构造时,声明了两个sensor分别是depth sensor、color sensor,OpenCore可以通过调用getSensorInfoList获取OzDevice中的sensor信息,然后调用createStream创建stream;
class DeviceBase{public: DeviceBase() {} virtual ~DeviceBase() {} virtual OniStatus getSensorInfoList(OniSensorInfo** pSensorInfos, int* numSensors) = 0; // 创建和销毁stream virtual StreamBase* createStream(OniSensorType) = 0; virtual void destroyStream(StreamBase* pStream) = 0;};class OzDevice : public oni::driver::DeviceBase{public: OzDevice(OniDeviceInfo* pInfo, oni::driver::DriverServices& driverServices) : m_pInfo(pInfo), m_driverServices(driverServices) { // 声明 sensor的个数和分辨率等信息 m_numSensors = 2; m_sensors[0].pSupportedVideoModes = XN_NEW_ARR(OniVideoMode, 1); m_sensors[0].sensorType = ONI_SENSOR_DEPTH; m_sensors[0].numSupportedVideoModes = 1; m_sensors[0].pSupportedVideoModes[0].pixelFormat = ONI_PIXEL_FORMAT_DEPTH_1_MM; m_sensors[0].pSupportedVideoModes[0].fps = 30; m_sensors[0].pSupportedVideoModes[0].resolutionX = OZ_RESOLUTION_X; m_sensors[0].pSupportedVideoModes[0].resolutionY = OZ_RESOLUTION_Y; m_sensors[1].pSupportedVideoModes = XN_NEW_ARR(OniVideoMode, 1); m_sensors[1].sensorType = ONI_SENSOR_COLOR; m_sensors[1].numSupportedVideoModes = 1; m_sensors[1].pSupportedVideoModes[0].pixelFormat = ONI_PIXEL_FORMAT_RGB888; m_sensors[1].pSupportedVideoModes[0].fps = 30; m_sensors[1].pSupportedVideoModes[0].resolutionX = OZ_RESOLUTION_X; m_sensors[1].pSupportedVideoModes[0].resolutionY = OZ_RESOLUTION_Y; } // 直接返回sensor的个数和信息 OniStatus getSensorInfoList(OniSensorInfo** pSensors, int* numSensors) { *numSensors = m_numSensors; *pSensors = m_sensors; return ONI_STATUS_OK; } oni::driver::StreamBase* createStream(OniSensorType sensorType) { // 直接new出 StreamBase if (sensorType == ONI_SENSOR_DEPTH) { OzDepthStream* pDepth = XN_NEW(OzDepthStream); return pDepth; } if (sensorType == ONI_SENSOR_COLOR) { OzImageStream* pImage = XN_NEW(OzImageStream); return pImage; } return NULL; } void destroyStream(oni::driver::StreamBase* pStream) { XN_DELETE(pStream); }private: int m_numSensors; OniSensorInfo m_sensors[10];};
StreamBase
StreamBase由DeviceBase 创建出来,主要对OpenCore提供图片信息,StreamServices是OpenCore注册的管理图片内存的类,StreamBase通过StreamServices申请图片内存,然后将图片填充到内存,之后调用m_newFrameCallback 将该图片提交给OpenCore;
class StreamBase{public: StreamBase() : m_newFrameCallback(NULL), m_propertyChangedCallback(NULL) {} virtual ~StreamBase() {} // 设置StreamServices 以供 stream申请图片内存使用 virtual void setServices(StreamServices* pStreamServices) { m_pServices = pStreamServices; } virtual int getRequiredFrameSize() { return getServices().getDefaultRequiredFrameSize(); } // stream 输出图片 start和stop virtual OniStatus start() = 0; virtual void stop() = 0; // 设置frame callback 回调函数, stream调用该函数通知OpenCore有新图片到达 virtual void setNewFrameCallback(NewFrameCallback handler, void* pCookie) { m_newFrameCallback = handler; m_newFrameCallbackCookie = pCookie; }protected: void raiseNewFrame(OniFrame* pFrame) { (*m_newFrameCallback)(this, pFrame, m_newFrameCallbackCookie); } StreamServices& getServices() { return *m_pServices; }private: StreamServices* m_pServices; NewFrameCallback m_newFrameCallback; void* m_newFrameCallbackCookie;};class StreamServices : public OniStreamServices{public: // 返回一帧图片的大小 int getDefaultRequiredFrameSize() // 申请一帧图片内存 OniFrame* acquireFrame() // 增加引用 void addFrameRef(OniFrame* pFrame) // 解引用 void releaseFrame(OniFrame* pFrame)};
通过上述分析,可以看出底层驱动的框架
- 浅析OpenNI2---Driver开发(2)
- 浅析OpenNI2---Driver开发(1)
- 浅析OpenNI2---简介
- 浅析OpenNI2---整体框架
- MongoDB&C++开发 (三) C++ Driver 浅析(结合mongo-cxx-driver/examples中代码)
- 浅析OpenNI2---Build System 与KDE
- OPENNI2+VS2015安装(win10)
- 基于OpenNI2(win64) 的Structure Sensor应用开发完整教程
- Mac下OpenNI2开发环境搭建
- 浅析 penmount9000系列 driver
- Kinect1代+KinectSDK1.8+OpenNI2.2+NITE2.0+Opencv2.4.10环境配置(2)
- Kinect1代+KinectSDK1.8+OpenNI2.2+NITE2.0环境配置(1)
- Kinect on Ubuntu with OpenNI2.2
- Kinect安装与配置(openNI2)
- Kinect开发:OpenNI2简介、安装与VS开发环境配置
- OpenNI2简介、安装与VS开发环境配置
- 搭建OpenCV 3.1、OpenNi2、Qt 5.5、VS2010开发环境
- android WIFI DRIVER 开发日记(三)
- centos7下glusterFs 分布式文件系统环境搭建
- JS解析json数据并将json字符串转化为数组的实现方法
- 03. 加权图的建模和相关算法
- jdk安装 path配置 tomcat安装
- linux下创建用户和添加用户权限
- 浅析OpenNI2---Driver开发(2)
- AI大潮之下,“造物主”码农也要失业了?【智库2861】
- 04. 图论算法-补充
- 一千年农历计算
- android studio的开发和使用SDK总结
- Windows并发&异步编程(1)JAVA&多线程
- c++17随想
- springmvc常用注解标签详解
- gperftools使用