00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef OPENNI_H
00022 #define OPENNI_H
00023
00024 #include "OniPlatform.h"
00025 #include "OniProperties.h"
00026 #include "OniEnums.h"
00027
00028 #include "OniCAPI.h"
00029 #include "OniCProperties.h"
00030 #include "OniCTypes.h"
00031
00035 namespace openni
00036 {
00037
00039 typedef uint16_t DepthPixel;
00040
00042 typedef uint16_t Grayscale16Pixel;
00043
00044
00046 typedef struct
00047 {
00049 int major;
00051 int minor;
00053 int maintenance;
00055 int build;
00056 } Version;
00057
00059 typedef struct
00060 {
00061
00062 uint8_t r;
00063
00064 uint8_t g;
00065
00066 uint8_t b;
00067 } RGB888Pixel;
00068
00074 typedef struct
00075 {
00077 uint8_t u;
00079 uint8_t y1;
00081 uint8_t v;
00083 uint8_t y2;
00084 } YUV422DoublePixel;
00085
00091 typedef struct
00092 {
00094 uint8_t y1;
00096 uint8_t u;
00098 uint8_t y2;
00100 uint8_t v;
00101 } YUYVDoublePixel;
00102
00104 class _NullString
00105 {
00106 public:
00107 _NullString() {}
00108 operator const char*() const { return NULL; }
00109 };
00110
00111 static const _NullString ANY_DEVICE;
00112
00117 template<class T>
00118 class Array
00119 {
00120 public:
00124 Array() : m_data(NULL), m_count(0), m_owner(false) {}
00125
00133 Array(const T* data, int count) : m_owner(false) { _setData(data, count); }
00134
00138 ~Array()
00139 {
00140 clear();
00141 }
00142
00147 int getSize() const { return m_count; }
00148
00152 const T& operator[](int index) const {return m_data[index];}
00153
00164 void _setData(const T* data, int count, bool isOwner = false)
00165 {
00166 clear();
00167 m_count = count;
00168 m_owner = isOwner;
00169 if (!isOwner)
00170 {
00171 m_data = data;
00172 }
00173 else
00174 {
00175 m_data = new T[count];
00176 memcpy((void*)m_data, data, count*sizeof(T));
00177 }
00178 }
00179
00180 private:
00181 Array(const Array<T>&);
00182 Array<T>& operator=(const Array<T>&);
00183
00184 void clear()
00185 {
00186 if (m_owner && m_data != NULL)
00187 delete []m_data;
00188 m_owner = false;
00189 m_data = NULL;
00190 m_count = 0;
00191 }
00192
00193 const T* m_data;
00194 int m_count;
00195 bool m_owner;
00196 };
00197
00198
00199 class SensorInfo;
00200 class VideoStream;
00201 class VideoFrameRef;
00202 class Device;
00203 class OpenNI;
00204 class CameraSettings;
00205 class PlaybackControl;
00206
00221 class VideoMode : private OniVideoMode
00222 {
00223 public:
00229 VideoMode()
00230 {}
00231
00237 VideoMode(const VideoMode& other)
00238 {
00239 *this = other;
00240 }
00241
00248 VideoMode& operator=(const VideoMode& other)
00249 {
00250 setPixelFormat(other.getPixelFormat());
00251 setResolution(other.getResolutionX(), other.getResolutionY());
00252 setFps(other.getFps());
00253
00254 return *this;
00255 }
00256
00261 PixelFormat getPixelFormat() const { return (PixelFormat)pixelFormat; }
00262
00267 int getResolutionX() const { return resolutionX; }
00268
00273 int getResolutionY() const {return resolutionY;}
00274
00279 int getFps() const { return fps; }
00280
00287 void setPixelFormat(PixelFormat format) { this->pixelFormat = (OniPixelFormat)format; }
00288
00296 void setResolution(int resolutionX, int resolutionY)
00297 {
00298 this->resolutionX = resolutionX;
00299 this->resolutionY = resolutionY;
00300 }
00301
00308 void setFps(int fps) { this->fps = fps; }
00309
00310 friend class SensorInfo;
00311 friend class VideoStream;
00312 friend class VideoFrameRef;
00313 };
00314
00332 class SensorInfo
00333 {
00334 public:
00339 SensorType getSensorType() const { return (SensorType)m_pInfo->sensorType; }
00340
00348 const Array<VideoMode>& getSupportedVideoModes() const { return m_videoModes; }
00349
00350 private:
00351 SensorInfo(const SensorInfo&);
00352 SensorInfo& operator=(const SensorInfo&);
00353
00354 SensorInfo() : m_pInfo(NULL), m_videoModes(NULL, 0) {}
00355
00356 SensorInfo(const OniSensorInfo* pInfo) : m_pInfo(NULL), m_videoModes(NULL, 0)
00357 {
00358 _setInternal(pInfo);
00359 }
00360
00361 void _setInternal(const OniSensorInfo* pInfo)
00362 {
00363 m_pInfo = pInfo;
00364 if (pInfo == NULL)
00365 {
00366 m_videoModes._setData(NULL, 0);
00367 }
00368 else
00369 {
00370 m_videoModes._setData(static_cast<VideoMode*>(pInfo->pSupportedVideoModes), pInfo->numSupportedVideoModes);
00371 }
00372 }
00373
00374 const OniSensorInfo* m_pInfo;
00375 Array<VideoMode> m_videoModes;
00376
00377 friend class VideoStream;
00378 friend class Device;
00379 };
00380
00390 class DeviceInfo : private OniDeviceInfo
00391 {
00392 public:
00397 const char* getUri() const { return uri; }
00399 const char* getVendor() const { return vendor; }
00401 const char* getName() const { return name; }
00403 uint16_t getUsbVendorId() const { return usbVendorId; }
00405 uint16_t getUsbProductId() const { return usbProductId; }
00406
00407 friend class Device;
00408 friend class OpenNI;
00409 };
00410
00424 class VideoFrameRef
00425 {
00426 public:
00431 VideoFrameRef()
00432 {
00433 m_pFrame = NULL;
00434 }
00435
00439 ~VideoFrameRef()
00440 {
00441 release();
00442 }
00443
00449 VideoFrameRef(const VideoFrameRef& other) : m_pFrame(NULL)
00450 {
00451 _setFrame(other.m_pFrame);
00452 }
00453
00459 VideoFrameRef& operator=(const VideoFrameRef& other)
00460 {
00461 _setFrame(other.m_pFrame);
00462 return *this;
00463 }
00464
00470 inline int getDataSize() const
00471 {
00472 return m_pFrame->dataSize;
00473 }
00474
00480 inline const void* getData() const
00481 {
00482 return m_pFrame->data;
00483 }
00484
00491 inline SensorType getSensorType() const
00492 {
00493 return (SensorType)m_pFrame->sensorType;
00494 }
00495
00503 inline const VideoMode& getVideoMode() const
00504 {
00505 return static_cast<const VideoMode&>(m_pFrame->videoMode);
00506 }
00507
00515 inline uint64_t getTimestamp() const
00516 {
00517 return m_pFrame->timestamp;
00518 }
00519
00530 inline int getFrameIndex() const
00531 {
00532 return m_pFrame->frameIndex;
00533 }
00534
00541 inline int getWidth() const
00542 {
00543 return m_pFrame->width;
00544 }
00545
00551 inline int getHeight() const
00552 {
00553 return m_pFrame->height;
00554 }
00555
00560 inline bool getCroppingEnabled() const
00561 {
00562 return m_pFrame->croppingEnabled == TRUE;
00563 }
00564
00569 inline int getCropOriginX() const
00570 {
00571 return m_pFrame->cropOriginX;
00572 }
00573
00578 inline int getCropOriginY() const
00579 {
00580 return m_pFrame->cropOriginY;
00581 }
00582
00588 inline int getStrideInBytes() const
00589 {
00590 return m_pFrame->stride;
00591 }
00592
00596 inline bool isValid() const
00597 {
00598 return m_pFrame != NULL;
00599 }
00600
00605 void release()
00606 {
00607 if (m_pFrame != NULL)
00608 {
00609 oniFrameRelease(m_pFrame);
00610 m_pFrame = NULL;
00611 }
00612 }
00613
00615 void _setFrame(OniFrame* pFrame)
00616 {
00617 setReference(pFrame);
00618 if (pFrame != NULL)
00619 {
00620 oniFrameAddRef(pFrame);
00621 }
00622 }
00623
00625 OniFrame* _getFrame()
00626 {
00627 return m_pFrame;
00628 }
00629
00630 private:
00631 friend class VideoStream;
00632 inline void setReference(OniFrame* pFrame)
00633 {
00634
00635 release();
00636 m_pFrame = pFrame;
00637 }
00638
00639 OniFrame* m_pFrame;
00640 };
00641
00663 class VideoStream
00664 {
00665 public:
00673 class NewFrameListener
00674 {
00675 public:
00679 NewFrameListener() : m_callbackHandle(NULL)
00680 {
00681 }
00682
00683 virtual ~NewFrameListener()
00684 {
00685 }
00686
00690 virtual void onNewFrame(VideoStream&) = 0;
00691
00692 private:
00693 friend class VideoStream;
00694
00695 static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie)
00696 {
00697 NewFrameListener* pListener = (NewFrameListener*)pCookie;
00698 VideoStream stream;
00699 stream._setHandle(streamHandle);
00700 pListener->onNewFrame(stream);
00701 stream._setHandle(NULL);
00702 }
00703 OniCallbackHandle m_callbackHandle;
00704 };
00705
00706 class FrameAllocator
00707 {
00708 public:
00709 virtual ~FrameAllocator() {}
00710 virtual void* allocateFrameBuffer(int size) = 0;
00711 virtual void freeFrameBuffer(void* data) = 0;
00712
00713 private:
00714 friend class VideoStream;
00715
00716 static void* ONI_CALLBACK_TYPE allocateFrameBufferCallback(int size, void* pCookie)
00717 {
00718 FrameAllocator* pThis = (FrameAllocator*)pCookie;
00719 return pThis->allocateFrameBuffer(size);
00720 }
00721
00722 static void ONI_CALLBACK_TYPE freeFrameBufferCallback(void* data, void* pCookie)
00723 {
00724 FrameAllocator* pThis = (FrameAllocator*)pCookie;
00725 pThis->freeFrameBuffer(data);
00726 }
00727 };
00728
00733 VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL), m_isOwner(true)
00734 {}
00735
00740 explicit VideoStream(OniStreamHandle handle) : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL), m_isOwner(false)
00741 {
00742 _setHandle(handle);
00743 }
00744
00749 ~VideoStream()
00750 {
00751 destroy();
00752 }
00753
00758 bool isValid() const
00759 {
00760 return m_stream != NULL;
00761 }
00762
00772 inline Status create(const Device& device, SensorType sensorType);
00773
00779 inline void destroy();
00780
00789 const SensorInfo& getSensorInfo() const
00790 {
00791 return m_sensorInfo;
00792 }
00793
00794 ParamsRegistrationMode getSoftwareRegistratorMode(){
00795
00796 ParamsRegistrationMode mode;
00797 Status rc = getProperty(STREAM_PROPERTY_SOFTWARE_REGISTRATION, &mode);
00798 if (rc != STATUS_OK)
00799 {
00800 return PARAMS_REGISTRATION_OFF;
00801 }
00802 return mode;
00803 }
00804
00805 void setSoftwareRegistrator(ParamsRegistrationMode mode){
00806 setProperty(STREAM_PROPERTY_SOFTWARE_REGISTRATION, (int)mode);
00807 }
00808
00812 Status start()
00813 {
00814 if (!isValid())
00815 {
00816 return STATUS_ERROR;
00817 }
00818
00819 return (Status)oniStreamStart(m_stream);
00820 }
00821
00825 void stop()
00826 {
00827 if (!isValid())
00828 {
00829 return;
00830 }
00831
00832 oniStreamStop(m_stream);
00833 }
00834
00845 Status readFrame(VideoFrameRef* pFrame)
00846 {
00847 if (!isValid())
00848 {
00849 return STATUS_ERROR;
00850 }
00851
00852 OniFrame* pOniFrame;
00853 Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame);
00854
00855 pFrame->setReference(pOniFrame);
00856 return rc;
00857 }
00858
00866 Status addNewFrameListener(NewFrameListener* pListener)
00867 {
00868 if (!isValid())
00869 {
00870 return STATUS_ERROR;
00871 }
00872
00873 return (Status)oniStreamRegisterNewFrameCallback(m_stream, pListener->callback, pListener, &pListener->m_callbackHandle);
00874 }
00875
00880 void removeNewFrameListener(NewFrameListener* pListener)
00881 {
00882 if (!isValid())
00883 {
00884 return;
00885 }
00886
00887 oniStreamUnregisterNewFrameCallback(m_stream, pListener->m_callbackHandle);
00888 pListener->m_callbackHandle = NULL;
00889 }
00890
00896 Status setFrameBuffersAllocator(FrameAllocator* pAllocator)
00897 {
00898 if (!isValid())
00899 {
00900 return STATUS_ERROR;
00901 }
00902
00903 if (pAllocator == NULL)
00904 {
00905 return (Status)oniStreamSetFrameBuffersAllocator(m_stream, NULL, NULL, NULL);
00906 }
00907 else
00908 {
00909 return (Status)oniStreamSetFrameBuffersAllocator(m_stream, pAllocator->allocateFrameBufferCallback, pAllocator->freeFrameBufferCallback, pAllocator);
00910 }
00911 }
00912
00917 OniStreamHandle _getHandle() const
00918 {
00919 return m_stream;
00920 }
00921
00926 CameraSettings* getCameraSettings() {return m_pCameraSettings;}
00927
00938 Status getProperty(int propertyId, void* data, int* dataSize) const
00939 {
00940 if (!isValid())
00941 {
00942 return STATUS_ERROR;
00943 }
00944
00945 return (Status)oniStreamGetProperty(m_stream, propertyId, data, dataSize);
00946 }
00947
00958 Status setProperty(int propertyId, const void* data, int dataSize)
00959 {
00960 if (!isValid())
00961 {
00962 return STATUS_ERROR;
00963 }
00964
00965 return (Status)oniStreamSetProperty(m_stream, propertyId, data, dataSize);
00966 }
00967
00974 VideoMode getVideoMode() const
00975 {
00976 VideoMode videoMode;
00977 getProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<OniVideoMode*>(&videoMode));
00978 return videoMode;
00979 }
00980
00989 Status setVideoMode(const VideoMode& videoMode)
00990 {
00991 return setProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<const OniVideoMode&>(videoMode));
00992 }
00993
00999 int getMaxPixelValue() const
01000 {
01001 int maxValue;
01002 Status rc = getProperty<int>(STREAM_PROPERTY_MAX_VALUE, &maxValue);
01003 if (rc != STATUS_OK)
01004 {
01005 return 0;
01006 }
01007 return maxValue;
01008 }
01009
01015 int getMinPixelValue() const
01016 {
01017 int minValue;
01018 Status rc = getProperty<int>(STREAM_PROPERTY_MIN_VALUE, &minValue);
01019 if (rc != STATUS_OK)
01020 {
01021 return 0;
01022 }
01023 return minValue;
01024 }
01025
01030 bool isCroppingSupported() const
01031 {
01032 return isPropertySupported(STREAM_PROPERTY_CROPPING);
01033 }
01034
01043 bool getCropping(int* pOriginX, int* pOriginY, int* pWidth, int* pHeight) const
01044 {
01045 OniCropping cropping;
01046 bool enabled = false;
01047
01048 Status rc = getProperty<OniCropping>(STREAM_PROPERTY_CROPPING, &cropping);
01049
01050 if (rc == STATUS_OK)
01051 {
01052 *pOriginX = cropping.originX;
01053 *pOriginY = cropping.originY;
01054 *pWidth = cropping.width;
01055 *pHeight = cropping.height;
01056 enabled = (cropping.enabled == TRUE);
01057 }
01058
01059 return enabled;
01060 }
01061
01071 Status setCropping(int originX, int originY, int width, int height)
01072 {
01073 OniCropping cropping;
01074 cropping.enabled = true;
01075 cropping.originX = originX;
01076 cropping.originY = originY;
01077 cropping.width = width;
01078 cropping.height = height;
01079 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping);
01080 }
01081
01086 Status resetCropping()
01087 {
01088 OniCropping cropping;
01089 cropping.enabled = false;
01090 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping);
01091 }
01092
01097 bool getMirroringEnabled() const
01098 {
01099 OniBool enabled;
01100 Status rc = getProperty<OniBool>(STREAM_PROPERTY_MIRRORING, &enabled);
01101 if (rc != STATUS_OK)
01102 {
01103 return false;
01104 }
01105 return enabled == TRUE;
01106 }
01107
01113 Status setMirroringEnabled(bool isEnabled)
01114 {
01115 return setProperty<OniBool>(STREAM_PROPERTY_MIRRORING, isEnabled ? TRUE : FALSE);
01116 }
01117
01122 float getHorizontalFieldOfView() const
01123 {
01124 float horizontal = 0;
01125 getProperty<float>(STREAM_PROPERTY_HORIZONTAL_FOV, &horizontal);
01126 return horizontal;
01127 }
01128
01133 float getVerticalFieldOfView() const
01134 {
01135 float vertical = 0;
01136 getProperty<float>(STREAM_PROPERTY_VERTICAL_FOV, &vertical);
01137 return vertical;
01138 }
01139
01149 template <class T>
01150 Status setProperty(int propertyId, const T& value)
01151 {
01152 return setProperty(propertyId, &value, sizeof(T));
01153 }
01154
01164 template <class T>
01165 Status getProperty(int propertyId, T* value) const
01166 {
01167 int size = sizeof(T);
01168 return getProperty(propertyId, value, &size);
01169 }
01170
01176 bool isPropertySupported(int propertyId) const
01177 {
01178 if (!isValid())
01179 {
01180 return false;
01181 }
01182
01183 return oniStreamIsPropertySupported(m_stream, propertyId) == TRUE;
01184 }
01185
01195 Status invoke(int commandId, void* data, int dataSize)
01196 {
01197 if (!isValid())
01198 {
01199 return STATUS_ERROR;
01200 }
01201
01202 return (Status)oniStreamInvoke(m_stream, commandId, data, dataSize);
01203 }
01204
01214 template <class T>
01215 Status invoke(int commandId, T& value)
01216 {
01217 return invoke(commandId, &value, sizeof(T));
01218 }
01219
01225 bool isCommandSupported(int commandId) const
01226 {
01227 if (!isValid())
01228 {
01229 return false;
01230 }
01231
01232 return (Status)oniStreamIsCommandSupported(m_stream, commandId) == TRUE;
01233 }
01234
01235 void filterSpeckles(void* buf, int newVal, int maxSpeckleSize, int maxDiff){
01236 oniStreamfilter(m_stream, buf, newVal, maxSpeckleSize, maxDiff);
01237 }
01238
01239 private:
01240 friend class Device;
01241
01242 void _setHandle(OniStreamHandle stream)
01243 {
01244 m_sensorInfo._setInternal(NULL);
01245 m_stream = stream;
01246
01247 if (stream != NULL)
01248 {
01249 m_sensorInfo._setInternal(oniStreamGetSensorInfo(m_stream));
01250 }
01251 }
01252
01253 private:
01254 VideoStream(const VideoStream& other);
01255 VideoStream& operator=(const VideoStream& other);
01256
01257 OniStreamHandle m_stream;
01258 SensorInfo m_sensorInfo;
01259 CameraSettings* m_pCameraSettings;
01260 bool m_isOwner;
01261 };
01262
01279 class Device
01280 {
01281 public:
01286 Device() : m_pPlaybackControl(NULL), m_device(NULL), m_isOwner(true)
01287 {
01288 clearSensors();
01289 }
01290
01295 explicit Device(OniDeviceHandle handle) : m_pPlaybackControl(NULL), m_device(NULL), m_isOwner(false)
01296 {
01297 _setHandle(handle);
01298 }
01299
01304 ~Device()
01305 {
01306 if (m_device != NULL)
01307 {
01308 close();
01309 }
01310 }
01311
01341 inline Status open(const char* uri);
01342
01348 inline void close();
01349
01359 const DeviceInfo& getDeviceInfo() const
01360 {
01361 return m_deviceInfo;
01362 }
01363
01371 bool hasSensor(SensorType sensorType)
01372 {
01373 int i;
01374 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i)
01375 {
01376 if (m_aSensorInfo[i].getSensorType() == sensorType)
01377 {
01378 return true;
01379 }
01380 }
01381
01382 if (i == ONI_MAX_SENSORS)
01383 {
01384 return false;
01385 }
01386
01387 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType);
01388
01389 if (pInfo == NULL)
01390 {
01391 return false;
01392 }
01393
01394 m_aSensorInfo[i]._setInternal(pInfo);
01395
01396 return true;
01397 }
01398
01406 const SensorInfo* getSensorInfo(SensorType sensorType)
01407 {
01408 int i;
01409 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i)
01410 {
01411 if (m_aSensorInfo[i].getSensorType() == sensorType)
01412 {
01413 return &m_aSensorInfo[i];
01414 }
01415 }
01416
01417
01418 if (i == ONI_MAX_SENSORS)
01419 {
01420 return NULL;
01421 }
01422
01423 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType);
01424 if (pInfo == NULL)
01425 {
01426 return NULL;
01427 }
01428
01429 m_aSensorInfo[i]._setInternal(pInfo);
01430 return &m_aSensorInfo[i];
01431 }
01432
01437 OniDeviceHandle _getHandle() const
01438 {
01439 return m_device;
01440 }
01441
01446 PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;}
01447
01459 Status getProperty(int propertyId, void* data, int* dataSize) const
01460 {
01461 return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize);
01462 }
01463
01475 Status setProperty(int propertyId, const void* data, int dataSize)
01476 {
01477 return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize);
01478 }
01479
01480 void setGain(int gain) {
01481 oniDeviceSetProperty(m_device, OBEXTENSION_ID_IR_GAIN, &gain, sizeof(gain));
01482 }
01483
01484 int getGain() {
01485 int value = 0;
01486 int size = sizeof(value);
01487 oniDeviceGetProperty(m_device, openni::OBEXTENSION_ID_IR_GAIN, (uint16_t *)&value, &size);
01488 return value;
01489 }
01497 bool isImageRegistrationModeSupported(ImageRegistrationMode mode) const
01498 {
01499 return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE);
01500 }
01501
01509 ImageRegistrationMode getImageRegistrationMode() const
01510 {
01511 ImageRegistrationMode mode;
01512 Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode);
01513 if (rc != STATUS_OK)
01514 {
01515 return IMAGE_REGISTRATION_OFF;
01516 }
01517 return mode;
01518 }
01519
01533 Status setImageRegistrationMode(ImageRegistrationMode mode)
01534 {
01535 return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode);
01536 }
01537
01542 bool isValid() const
01543 {
01544 return m_device != NULL;
01545 }
01546
01551 bool isFile() const
01552 {
01553 return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) &&
01554 isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) &&
01555 isCommandSupported(DEVICE_COMMAND_SEEK);
01556 }
01557
01566 Status setDepthColorSyncEnabled(bool isEnabled)
01567 {
01568 Status rc = STATUS_OK;
01569
01570 if (isEnabled)
01571 {
01572 rc = (Status)oniDeviceEnableDepthColorSync(m_device);
01573 }
01574 else
01575 {
01576 oniDeviceDisableDepthColorSync(m_device);
01577 }
01578
01579 return rc;
01580 }
01581
01582 bool getDepthColorSyncEnabled()
01583 {
01584 return oniDeviceGetDepthColorSyncEnabled(m_device) == TRUE;
01585 }
01586
01597 template <class T>
01598 Status setProperty(int propertyId, const T& value)
01599 {
01600 return setProperty(propertyId, &value, sizeof(T));
01601 }
01602
01612 template <class T>
01613 Status getProperty(int propertyId, T* value) const
01614 {
01615 int size = sizeof(T);
01616 return getProperty(propertyId, value, &size);
01617 }
01618
01624 bool isPropertySupported(int propertyId) const
01625 {
01626 return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE;
01627 }
01628
01638 Status invoke(int commandId, void* data, int dataSize)
01639 {
01640 return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize);
01641 }
01642
01652 template <class T>
01653 Status invoke(int propertyId, T& value)
01654 {
01655 return invoke(propertyId, &value, sizeof(T));
01656 }
01657
01663 bool isCommandSupported(int commandId) const
01664 {
01665 return oniDeviceIsCommandSupported(m_device, commandId) == TRUE;
01666 }
01667
01669 inline Status _openEx(const char* uri, const char* mode);
01670
01671 private:
01672 Device(const Device&);
01673 Device& operator=(const Device&);
01674
01675 void clearSensors()
01676 {
01677 for (int i = 0; i < ONI_MAX_SENSORS; ++i)
01678 {
01679 m_aSensorInfo[i]._setInternal(NULL);
01680 }
01681 }
01682
01683 inline Status _setHandle(OniDeviceHandle deviceHandle);
01684
01685 private:
01686 PlaybackControl* m_pPlaybackControl;
01687
01688 OniDeviceHandle m_device;
01689 DeviceInfo m_deviceInfo;
01690 SensorInfo m_aSensorInfo[ONI_MAX_SENSORS];
01691
01692 bool m_isOwner;
01693 };
01694
01708 class PlaybackControl
01709 {
01710 public:
01711
01717 ~PlaybackControl()
01718 {
01719 detach();
01720 }
01721
01742 float getSpeed() const
01743 {
01744 if (!isValid())
01745 {
01746 return 0.0f;
01747 }
01748 float speed;
01749 Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed);
01750 if (rc != STATUS_OK)
01751 {
01752 return 1.0f;
01753 }
01754 return speed;
01755 }
01763 Status setSpeed(float speed)
01764 {
01765 if (!isValid())
01766 {
01767 return STATUS_NO_DEVICE;
01768 }
01769 return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed);
01770 }
01771
01777 bool getRepeatEnabled() const
01778 {
01779 if (!isValid())
01780 {
01781 return false;
01782 }
01783
01784 OniBool repeat;
01785 Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat);
01786 if (rc != STATUS_OK)
01787 {
01788 return false;
01789 }
01790
01791 return repeat == TRUE;
01792 }
01793
01802 Status setRepeatEnabled(bool repeat)
01803 {
01804 if (!isValid())
01805 {
01806 return STATUS_NO_DEVICE;
01807 }
01808
01809 return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE);
01810 }
01811
01822 Status seek(const VideoStream& stream, int frameIndex)
01823 {
01824 if (!isValid())
01825 {
01826 return STATUS_NO_DEVICE;
01827 }
01828 OniSeek seek;
01829 seek.frameIndex = frameIndex;
01830 seek.stream = stream._getHandle();
01831 return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek);
01832 }
01833
01842 int getNumberOfFrames(const VideoStream& stream) const
01843 {
01844 int numOfFrames = -1;
01845 Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames);
01846 if (rc != STATUS_OK)
01847 {
01848 return 0;
01849 }
01850 return numOfFrames;
01851 }
01852
01853 bool isValid() const
01854 {
01855 return m_pDevice != NULL;
01856 }
01857 private:
01858 Status attach(Device* device)
01859 {
01860 if (!device->isValid() || !device->isFile())
01861 {
01862 return STATUS_ERROR;
01863 }
01864
01865 detach();
01866 m_pDevice = device;
01867
01868 return STATUS_OK;
01869 }
01870 void detach()
01871 {
01872 m_pDevice = NULL;
01873 }
01874
01875 friend class Device;
01876 PlaybackControl(Device* pDevice) : m_pDevice(NULL)
01877 {
01878 if (pDevice != NULL)
01879 {
01880 attach(pDevice);
01881 }
01882 }
01883
01884 Device* m_pDevice;
01885 };
01886
01887 class CameraSettings
01888 {
01889 public:
01890
01891 Status setAutoExposureEnabled(bool enabled)
01892 {
01893 return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE);
01894 }
01895 Status setAutoWhiteBalanceEnabled(bool enabled)
01896 {
01897 return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE);
01898 }
01899
01900 bool getAutoExposureEnabled() const
01901 {
01902 OniBool enabled = FALSE;
01903
01904 Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled);
01905 return rc == STATUS_OK && enabled == TRUE;
01906 }
01907 bool getAutoWhiteBalanceEnabled() const
01908 {
01909 OniBool enabled = FALSE;
01910
01911 Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled);
01912 return rc == STATUS_OK && enabled == TRUE;
01913 }
01914
01915 Status setGain(int gain)
01916 {
01917 return setProperty(STREAM_PROPERTY_GAIN, gain);
01918 }
01919 Status setExposure(int exposure)
01920 {
01921 return setProperty(STREAM_PROPERTY_EXPOSURE, exposure);
01922 }
01923 int getGain()
01924 {
01925 int gain;
01926 Status rc = getProperty(STREAM_PROPERTY_GAIN, &gain);
01927 if (rc != STATUS_OK)
01928 {
01929 return 100;
01930 }
01931 return gain;
01932 }
01933 int getExposure()
01934 {
01935 int exposure;
01936 Status rc = getProperty(STREAM_PROPERTY_EXPOSURE, &exposure);
01937 if (rc != STATUS_OK)
01938 {
01939 return 0;
01940 }
01941 return exposure;
01942 }
01943
01944 bool isValid() const {return m_pStream != NULL;}
01945 private:
01946 template <class T>
01947 Status getProperty(int propertyId, T* value) const
01948 {
01949 if (!isValid()) return STATUS_NOT_SUPPORTED;
01950
01951 return m_pStream->getProperty<T>(propertyId, value);
01952 }
01953 template <class T>
01954 Status setProperty(int propertyId, const T& value)
01955 {
01956 if (!isValid()) return STATUS_NOT_SUPPORTED;
01957
01958 return m_pStream->setProperty<T>(propertyId, value);
01959 }
01960
01961 friend class VideoStream;
01962 CameraSettings(VideoStream* pStream)
01963 {
01964 m_pStream = pStream;
01965 }
01966
01967 VideoStream* m_pStream;
01968 };
01969
01970
01983 class OpenNI
01984 {
01985 public:
01986
02002 class DeviceConnectedListener
02003 {
02004 public:
02005 DeviceConnectedListener()
02006 {
02007 m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback;
02008 m_deviceConnectedCallbacks.deviceDisconnected = NULL;
02009 m_deviceConnectedCallbacks.deviceStateChanged = NULL;
02010 m_deviceConnectedCallbacksHandle = NULL;
02011 }
02012
02013 virtual ~DeviceConnectedListener()
02014 {
02015 }
02016
02028 virtual void onDeviceConnected(const DeviceInfo*) = 0;
02029 private:
02030 static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie)
02031 {
02032 DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie;
02033 pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo));
02034 }
02035
02036 friend class OpenNI;
02037 OniDeviceCallbacks m_deviceConnectedCallbacks;
02038 OniCallbackHandle m_deviceConnectedCallbacksHandle;
02039
02040 };
02057 class DeviceDisconnectedListener
02058 {
02059 public:
02060 DeviceDisconnectedListener()
02061 {
02062 m_deviceDisconnectedCallbacks.deviceConnected = NULL;
02063 m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback;
02064 m_deviceDisconnectedCallbacks.deviceStateChanged = NULL;
02065 m_deviceDisconnectedCallbacksHandle = NULL;
02066 }
02067
02068 virtual ~DeviceDisconnectedListener()
02069 {
02070 }
02071
02080 virtual void onDeviceDisconnected(const DeviceInfo*) = 0;
02081 private:
02082 static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie)
02083 {
02084 DeviceDisconnectedListener* pListener = (DeviceDisconnectedListener*)pCookie;
02085 pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo));
02086 }
02087
02088 friend class OpenNI;
02089 OniDeviceCallbacks m_deviceDisconnectedCallbacks;
02090 OniCallbackHandle m_deviceDisconnectedCallbacksHandle;
02091 };
02105 class DeviceStateChangedListener
02106 {
02107 public:
02108 DeviceStateChangedListener()
02109 {
02110 m_deviceStateChangedCallbacks.deviceConnected = NULL;
02111 m_deviceStateChangedCallbacks.deviceDisconnected = NULL;
02112 m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback;
02113 m_deviceStateChangedCallbacksHandle = NULL;
02114 }
02115
02116 virtual ~DeviceStateChangedListener()
02117 {
02118 }
02119
02126 virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0;
02127 private:
02128 static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie)
02129 {
02130 DeviceStateChangedListener* pListener = (DeviceStateChangedListener*)pCookie;
02131 pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state));
02132 }
02133
02134 friend class OpenNI;
02135 OniDeviceCallbacks m_deviceStateChangedCallbacks;
02136 OniCallbackHandle m_deviceStateChangedCallbacksHandle;
02137 };
02138
02144 static Status initialize()
02145 {
02146 return (Status)oniInitialize(ONI_API_VERSION);
02147 }
02148
02153 static void shutdown()
02154 {
02155 oniShutdown();
02156 }
02157
02161 static Version getVersion()
02162 {
02163 OniVersion oniVersion = oniGetVersion();
02164 Version version;
02165 version.major = oniVersion.major;
02166 version.minor = oniVersion.minor;
02167 version.maintenance = oniVersion.maintenance;
02168 version.build = oniVersion.build;
02169 return version;
02170 }
02171
02179 static const char* getExtendedError()
02180 {
02181 return oniGetExtendedError();
02182 }
02183
02188 static void enumerateDevices(Array<DeviceInfo>* deviceInfoList)
02189 {
02190 OniDeviceInfo* m_pDeviceInfos;
02191 int m_deviceInfoCount;
02192 oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount);
02193 deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true);
02194 oniReleaseDeviceList(m_pDeviceInfos);
02195 }
02196
02205 static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER)
02206 {
02207 static const int ONI_MAX_STREAMS = 50;
02208 OniStreamHandle streams[ONI_MAX_STREAMS];
02209
02210 if (streamCount > ONI_MAX_STREAMS)
02211 {
02212 printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS);
02213 return STATUS_BAD_PARAMETER;
02214 }
02215
02216 *pReadyStreamIndex = -1;
02217 for (int i = 0; i < streamCount; ++i)
02218 {
02219 if (pStreams[i] != NULL)
02220 {
02221 streams[i] = pStreams[i]->_getHandle();
02222 }
02223 else
02224 {
02225 streams[i] = NULL;
02226 }
02227 }
02228 Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout);
02229
02230 return rc;
02231 }
02232
02240 static Status addDeviceConnectedListener(DeviceConnectedListener* pListener)
02241 {
02242 if (pListener->m_deviceConnectedCallbacksHandle != NULL)
02243 {
02244 return STATUS_ERROR;
02245 }
02246 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle);
02247 }
02255 static Status addDeviceDisconnectedListener(DeviceDisconnectedListener* pListener)
02256 {
02257 if (pListener->m_deviceDisconnectedCallbacksHandle != NULL)
02258 {
02259 return STATUS_ERROR;
02260 }
02261 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle);
02262 }
02270 static Status addDeviceStateChangedListener(DeviceStateChangedListener* pListener)
02271 {
02272 if (pListener->m_deviceStateChangedCallbacksHandle != NULL)
02273 {
02274 return STATUS_ERROR;
02275 }
02276 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle);
02277 }
02285 static void removeDeviceConnectedListener(DeviceConnectedListener* pListener)
02286 {
02287 oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle);
02288 pListener->m_deviceConnectedCallbacksHandle = NULL;
02289 }
02297 static void removeDeviceDisconnectedListener(DeviceDisconnectedListener* pListener)
02298 {
02299 oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle);
02300 pListener->m_deviceDisconnectedCallbacksHandle = NULL;
02301 }
02309 static void removeDeviceStateChangedListener(DeviceStateChangedListener* pListener)
02310 {
02311 oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle);
02312 pListener->m_deviceStateChangedCallbacksHandle = NULL;
02313 }
02314
02323 static Status setLogOutputFolder(const char *strLogOutputFolder)
02324 {
02325 return (Status)oniSetLogOutputFolder(strLogOutputFolder);
02326 }
02327
02337 static Status getLogFileName(char *strFileName, int nBufferSize)
02338 {
02339 return (Status)oniGetLogFileName(strFileName, nBufferSize);
02340 }
02341
02350 static Status setLogMinSeverity(int nMinSeverity)
02351 {
02352 return(Status) oniSetLogMinSeverity(nMinSeverity);
02353 }
02354
02363 static Status setLogConsoleOutput(bool bConsoleOutput)
02364 {
02365 return (Status)oniSetLogConsoleOutput(bConsoleOutput);
02366 }
02367
02376 static Status setLogFileOutput(bool bFileOutput)
02377 {
02378 return (Status)oniSetLogFileOutput(bFileOutput);
02379 }
02380
02381 #if ONI_PLATFORM == ONI_PLATFORM_ANDROID_ARM
02382
02391 static Status setLogAndroidOutput(bool bAndroidOutput)
02392 {
02393 return (Status)oniSetLogAndroidOutput(bAndroidOutput);
02394 }
02395 #endif
02396
02397 private:
02398 OpenNI()
02399 {
02400 }
02401 };
02402
02438 class CoordinateConverter
02439 {
02440 public:
02451 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ)
02452 {
02453 float depthX, depthY, depthZ;
02454 Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ);
02455 *pDepthX = (int)depthX;
02456 *pDepthY = (int)depthY;
02457 *pDepthZ = (DepthPixel)depthZ;
02458 return rc;
02459 }
02460
02471 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ)
02472 {
02473 return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ);
02474 }
02475
02486 static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ)
02487 {
02488 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ);
02489 }
02490
02501 static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ)
02502 {
02503 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ);
02504 }
02505
02517 static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY)
02518 {
02519 return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY);
02520 }
02521
02522 static Status convertC2DCoordinateByIntrinsic(const VideoStream& depthStream, int colorX, int colorY, DepthPixel depthZ, int* pDepthX, int* pDepthY)
02523 {
02524 return (Status)oniCoordinateConverterC2D(depthStream._getHandle(), colorX, colorY, depthZ, pDepthX, pDepthY);
02525 }
02526 static Status convertD2CCoordinateByIntrinsic(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY)
02527 {
02528 return (Status)oniCoordinateConverterD2C(depthStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY);
02529 }
02530 };
02531
02546 class Recorder
02547 {
02548 public:
02553 Recorder() : m_recorder(NULL)
02554 {
02555 }
02556
02560 ~Recorder()
02561 {
02562 destroy();
02563 }
02564
02576 Status create(const char* fileName)
02577 {
02578 if (!isValid())
02579 {
02580 return (Status)oniCreateRecorder(fileName, &m_recorder);
02581 }
02582 return STATUS_ERROR;
02583 }
02584
02591 bool isValid() const
02592 {
02593 return NULL != getHandle();
02594 }
02595
02606 Status attach(VideoStream& stream, bool allowLossyCompression = false)
02607 {
02608 if (!isValid() || !stream.isValid())
02609 {
02610 return STATUS_ERROR;
02611 }
02612 return (Status)oniRecorderAttachStream(
02613 m_recorder,
02614 stream._getHandle(),
02615 allowLossyCompression);
02616 }
02617
02624 Status start()
02625 {
02626 if (!isValid())
02627 {
02628 return STATUS_ERROR;
02629 }
02630 return (Status)oniRecorderStart(m_recorder);
02631 }
02632
02636 void stop()
02637 {
02638 if (isValid())
02639 {
02640 oniRecorderStop(m_recorder);
02641 }
02642 }
02643
02647 void destroy()
02648 {
02649 if (isValid())
02650 {
02651 oniRecorderDestroy(&m_recorder);
02652 }
02653 }
02654
02655 private:
02656 Recorder(const Recorder&);
02657 Recorder& operator=(const Recorder&);
02658
02662 OniRecorderHandle getHandle() const
02663 {
02664 return m_recorder;
02665 }
02666
02667
02668 OniRecorderHandle m_recorder;
02669 };
02670
02671
02672 Status VideoStream::create(const Device& device, SensorType sensorType)
02673 {
02674 OniStreamHandle streamHandle;
02675 Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle);
02676 if (rc != STATUS_OK)
02677 {
02678 return rc;
02679 }
02680
02681 m_isOwner = true;
02682 _setHandle(streamHandle);
02683
02684 if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE))
02685 {
02686 m_pCameraSettings = new CameraSettings(this);
02687 }
02688
02689 return STATUS_OK;
02690 }
02691
02692 void VideoStream::destroy()
02693 {
02694 if (!isValid())
02695 {
02696 return;
02697 }
02698
02699 if (m_pCameraSettings != NULL)
02700 {
02701 delete m_pCameraSettings;
02702 m_pCameraSettings = NULL;
02703 }
02704
02705 if (m_stream != NULL)
02706 {
02707 if(m_isOwner)
02708 oniStreamDestroy(m_stream);
02709 m_stream = NULL;
02710 }
02711 }
02712
02713 Status Device::open(const char* uri)
02714 {
02715
02716 if(!m_isOwner)
02717 {
02718 if(isValid()){
02719 return STATUS_OK;
02720 }else{
02721 return STATUS_OUT_OF_FLOW;
02722 }
02723 }
02724
02725 OniDeviceHandle deviceHandle;
02726 Status rc = (Status)oniDeviceOpen(uri, &deviceHandle);
02727 if (rc != STATUS_OK)
02728 {
02729 return rc;
02730 }
02731
02732 _setHandle(deviceHandle);
02733
02734 return STATUS_OK;
02735 }
02736
02737 Status Device::_openEx(const char* uri, const char* mode)
02738 {
02739
02740 if(!m_isOwner)
02741 {
02742 if(isValid()){
02743 return STATUS_OK;
02744 }else{
02745 return STATUS_OUT_OF_FLOW;
02746 }
02747 }
02748
02749 OniDeviceHandle deviceHandle;
02750 Status rc = (Status)oniDeviceOpenEx(uri, mode, &deviceHandle);
02751 if (rc != STATUS_OK)
02752 {
02753 return rc;
02754 }
02755
02756 _setHandle(deviceHandle);
02757
02758 return STATUS_OK;
02759 }
02760
02761 Status Device::_setHandle(OniDeviceHandle deviceHandle)
02762 {
02763 if (m_device == NULL)
02764 {
02765 m_device = deviceHandle;
02766
02767 clearSensors();
02768
02769 oniDeviceGetInfo(m_device, &m_deviceInfo);
02770
02771 if (isFile())
02772 {
02773 m_pPlaybackControl = new PlaybackControl(this);
02774 }
02775
02776
02777 return STATUS_OK;
02778 }
02779
02780 return STATUS_OUT_OF_FLOW;
02781 }
02782
02783 void Device::close()
02784 {
02785 if (m_pPlaybackControl != NULL)
02786 {
02787 delete m_pPlaybackControl;
02788 m_pPlaybackControl = NULL;
02789 }
02790
02791 if (m_device != NULL)
02792 {
02793 if(m_isOwner)
02794 {
02795 oniDeviceClose(m_device);
02796 }
02797
02798 m_device = NULL;
02799 }
02800 }
02801
02802 }
02803
02804 #endif // OPENNI_H