浅析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)};

通过上述分析,可以看出底层驱动的框架

这里写图片描述