![]() |
OpenNI 2.0
|
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 2.x Alpha * 00004 * Copyright (C) 2012 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); * 00009 * you may not use this file except in compliance with the License. * 00010 * You may obtain a copy of the License at * 00011 * * 00012 * http://www.apache.org/licenses/LICENSE-2.0 * 00013 * * 00014 * Unless required by applicable law or agreed to in writing, software * 00015 * distributed under the License is distributed on an "AS IS" BASIS, * 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00017 * See the License for the specific language governing permissions and * 00018 * limitations under the License. * 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 00034 namespace openni 00035 { 00036 00038 typedef uint16_t DepthPixel; 00040 typedef uint16_t Grayscale16Pixel; 00041 00042 // structs 00043 _ONI_DECLARE_VERSION(Version); 00044 _ONI_DECLARE_RGB888_PIXEL(RGB888Pixel); 00045 _ONI_DECLARE_YUV422_PIXEL(YUV422DoublePixel); 00046 00048 #if ONI_PLATFORM != ONI_PLATFORM_WIN32 00049 #pragma GCC diagnostic ignored "-Wunused-variable" 00050 #pragma GCC diagnostic push 00051 #endif 00052 static const char* ANY_DEVICE = NULL; 00053 #if ONI_PLATFORM != ONI_PLATFORM_WIN32 00054 #pragma GCC diagnostic pop 00055 #endif 00056 00061 template<class T> 00062 class Array 00063 { 00064 public: 00068 Array() : m_data(NULL), m_count(0), m_owner(false) {} 00069 00077 Array(const T* data, int count) : m_owner(false) { _setData(data, count); } 00078 00082 ~Array() 00083 { 00084 clear(); 00085 } 00086 00091 int getSize() const { return m_count; } 00092 00096 const T& operator[](int index) const {return m_data[index];} 00097 00108 void _setData(const T* data, int count, bool isOwner = false) 00109 { 00110 clear(); 00111 m_count = count; 00112 m_owner = isOwner; 00113 if (!isOwner) 00114 { 00115 m_data = data; 00116 } 00117 else 00118 { 00119 m_data = new T[count]; 00120 memcpy((void*)m_data, data, count*sizeof(T)); 00121 } 00122 } 00123 00124 private: 00125 Array(const Array<T>&); 00126 Array<T>& operator=(const Array<T>&); 00127 00128 void clear() 00129 { 00130 if (m_owner && m_data != NULL) 00131 delete []m_data; 00132 m_owner = false; 00133 m_data = NULL; 00134 m_count = 0; 00135 } 00136 00137 const T* m_data; 00138 int m_count; 00139 bool m_owner; 00140 }; 00141 00142 // Forward declaration of all 00143 class SensorInfo; 00144 class VideoStream; 00145 class VideoFrameRef; 00146 class Device; 00147 class OpenNI; 00148 class CameraSettings; 00149 class PlaybackControl; 00150 00165 class VideoMode : private OniVideoMode 00166 { 00167 public: 00173 VideoMode() 00174 {} 00175 00181 VideoMode(const VideoMode& other) 00182 { 00183 *this = other; 00184 } 00185 00192 VideoMode& operator=(const VideoMode& other) 00193 { 00194 setPixelFormat(other.getPixelFormat()); 00195 setResolution(other.getResolutionX(), other.getResolutionY()); 00196 setFps(other.getFps()); 00197 00198 return *this; 00199 } 00200 00205 PixelFormat getPixelFormat() const { return (PixelFormat)pixelFormat; } 00206 00211 int getResolutionX() const { return resolutionX; } 00212 00217 int getResolutionY() const {return resolutionY;} 00218 00223 int getFps() const { return fps; } 00224 00231 void setPixelFormat(PixelFormat format) { this->pixelFormat = (OniPixelFormat)format; } 00232 00240 void setResolution(int resolutionX, int resolutionY) 00241 { 00242 this->resolutionX = resolutionX; 00243 this->resolutionY = resolutionY; 00244 } 00245 00252 void setFps(int fps) { this->fps = fps; } 00253 00254 friend class SensorInfo; 00255 friend class VideoStream; 00256 friend class VideoFrameRef; 00257 }; 00258 00276 class SensorInfo 00277 { 00278 public: 00283 SensorType getSensorType() const { return (SensorType)m_pInfo->sensorType; } 00284 00292 const Array<VideoMode>& getSupportedVideoModes() const { return m_videoModes; } 00293 00294 private: 00295 SensorInfo(const SensorInfo&); 00296 SensorInfo& operator=(const SensorInfo&); 00297 00298 SensorInfo() : m_pInfo(NULL), m_videoModes(NULL, 0) {} 00299 00300 SensorInfo(const OniSensorInfo* pInfo) : m_pInfo(NULL), m_videoModes(NULL, 0) 00301 { 00302 _setInternal(pInfo); 00303 } 00304 00305 void _setInternal(const OniSensorInfo* pInfo) 00306 { 00307 m_pInfo = pInfo; 00308 if (pInfo == NULL) 00309 { 00310 m_videoModes._setData(NULL, 0); 00311 } 00312 else 00313 { 00314 m_videoModes._setData(static_cast<VideoMode*>(pInfo->pSupportedVideoModes), pInfo->numSupportedVideoModes); 00315 } 00316 } 00317 00318 const OniSensorInfo* m_pInfo; 00319 Array<VideoMode> m_videoModes; 00320 00321 friend class VideoStream; 00322 friend class Device; 00323 }; 00324 00334 class DeviceInfo : private OniDeviceInfo 00335 { 00336 public: 00341 const char* getUri() const { return uri; } 00343 const char* getVendor() const { return vendor; } 00345 const char* getName() const { return name; } 00347 uint16_t getUsbVendorId() const { return usbVendorId; } 00349 uint16_t getUsbProductId() const { return usbProductId; } 00350 00351 friend class Device; 00352 friend class OpenNI; 00353 }; 00354 00368 class VideoFrameRef 00369 { 00370 public: 00375 VideoFrameRef() 00376 { 00377 m_pFrame = NULL; 00378 } 00379 00383 ~VideoFrameRef() 00384 { 00385 release(); 00386 } 00387 00393 VideoFrameRef(const VideoFrameRef& other) : m_pFrame(NULL) 00394 { 00395 _setFrame(other.m_pFrame); 00396 } 00397 00403 VideoFrameRef& operator=(const VideoFrameRef& other) 00404 { 00405 _setFrame(other.m_pFrame); 00406 return *this; 00407 } 00408 00414 inline int getDataSize() const 00415 { 00416 return m_pFrame->dataSize; 00417 } 00418 00424 inline const void* getData() const 00425 { 00426 return m_pFrame->data; 00427 } 00428 00435 inline SensorType getSensorType() const 00436 { 00437 return (SensorType)m_pFrame->sensorType; 00438 } 00439 00447 inline const VideoMode& getVideoMode() const 00448 { 00449 return static_cast<const VideoMode&>(m_pFrame->videoMode); 00450 } 00451 00459 inline uint64_t getTimestamp() const 00460 { 00461 return m_pFrame->timestamp; 00462 } 00463 00474 inline int getFrameIndex() const 00475 { 00476 return m_pFrame->frameIndex; 00477 } 00478 00485 inline int getWidth() const 00486 { 00487 return m_pFrame->width; 00488 } 00489 00495 inline int getHeight() const 00496 { 00497 return m_pFrame->height; 00498 } 00499 00504 inline bool getCroppingEnabled() const 00505 { 00506 return m_pFrame->croppingEnabled == TRUE; 00507 } 00508 00513 inline int getCropOriginX() const 00514 { 00515 return m_pFrame->cropOriginX; 00516 } 00517 00522 inline int getCropOriginY() const 00523 { 00524 return m_pFrame->cropOriginY; 00525 } 00526 00532 inline int getStrideInBytes() const 00533 { 00534 return m_pFrame->stride; 00535 } 00536 00540 inline bool isValid() const 00541 { 00542 return m_pFrame != NULL; 00543 } 00544 00549 void release() 00550 { 00551 if (m_pFrame != NULL) 00552 { 00553 oniFrameRelease(m_pFrame); 00554 m_pFrame = NULL; 00555 } 00556 } 00557 00559 void _setFrame(OniFrame* pFrame) 00560 { 00561 setReference(pFrame); 00562 if (pFrame != NULL) 00563 { 00564 oniFrameAddRef(pFrame); 00565 } 00566 } 00567 00569 OniFrame* _getFrame() 00570 { 00571 return m_pFrame; 00572 } 00573 00574 private: 00575 friend class VideoStream; 00576 inline void setReference(OniFrame* pFrame) 00577 { 00578 // Initial - don't addref. This is the reference from OpenNI 00579 release(); 00580 m_pFrame = pFrame; 00581 } 00582 00583 OniFrame* m_pFrame; // const!!? 00584 }; 00585 00607 class VideoStream 00608 { 00609 public: 00617 class NewFrameListener 00618 { 00619 public: 00623 NewFrameListener() : m_callbackHandle(NULL) 00624 { 00625 } 00626 00627 virtual ~NewFrameListener() 00628 { 00629 } 00630 00634 virtual void onNewFrame(VideoStream&) = 0; 00635 00636 private: 00637 friend class VideoStream; 00638 00639 static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie) 00640 { 00641 NewFrameListener* pListener = (NewFrameListener*)pCookie; 00642 VideoStream stream; 00643 stream._setHandle(streamHandle); 00644 pListener->onNewFrame(stream); 00645 stream._setHandle(NULL); 00646 } 00647 OniCallbackHandle m_callbackHandle; 00648 }; 00649 00650 class FrameAllocator 00651 { 00652 public: 00653 virtual ~FrameAllocator() {} 00654 virtual void* allocateFrameBuffer(int size) = 0; 00655 virtual void freeFrameBuffer(void* data) = 0; 00656 00657 private: 00658 friend class VideoStream; 00659 00660 static void* ONI_CALLBACK_TYPE allocateFrameBufferCallback(int size, void* pCookie) 00661 { 00662 FrameAllocator* pThis = (FrameAllocator*)pCookie; 00663 return pThis->allocateFrameBuffer(size); 00664 } 00665 00666 static void ONI_CALLBACK_TYPE freeFrameBufferCallback(void* data, void* pCookie) 00667 { 00668 FrameAllocator* pThis = (FrameAllocator*)pCookie; 00669 pThis->freeFrameBuffer(data); 00670 } 00671 }; 00672 00677 VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL), m_isOwner(true) 00678 {} 00679 00684 explicit VideoStream(OniStreamHandle handle) : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL), m_isOwner(false) 00685 { 00686 _setHandle(handle); 00687 } 00688 00693 ~VideoStream() 00694 { 00695 destroy(); 00696 } 00697 00702 bool isValid() const 00703 { 00704 return m_stream != NULL; 00705 } 00706 00716 inline Status create(const Device& device, SensorType sensorType); 00717 00723 inline void destroy(); 00724 00733 const SensorInfo& getSensorInfo() const 00734 { 00735 return m_sensorInfo; 00736 } 00737 00741 Status start() 00742 { 00743 if (!isValid()) 00744 { 00745 return STATUS_ERROR; 00746 } 00747 00748 return (Status)oniStreamStart(m_stream); 00749 } 00750 00754 void stop() 00755 { 00756 if (!isValid()) 00757 { 00758 return; 00759 } 00760 00761 oniStreamStop(m_stream); 00762 } 00763 00774 Status readFrame(VideoFrameRef* pFrame) 00775 { 00776 if (!isValid()) 00777 { 00778 return STATUS_ERROR; 00779 } 00780 00781 OniFrame* pOniFrame; 00782 Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame); 00783 00784 pFrame->setReference(pOniFrame); 00785 return rc; 00786 } 00787 00795 Status addNewFrameListener(NewFrameListener* pListener) 00796 { 00797 if (!isValid()) 00798 { 00799 return STATUS_ERROR; 00800 } 00801 00802 return (Status)oniStreamRegisterNewFrameCallback(m_stream, pListener->callback, pListener, &pListener->m_callbackHandle); 00803 } 00804 00809 void removeNewFrameListener(NewFrameListener* pListener) 00810 { 00811 if (!isValid()) 00812 { 00813 return; 00814 } 00815 00816 oniStreamUnregisterNewFrameCallback(m_stream, pListener->m_callbackHandle); 00817 pListener->m_callbackHandle = NULL; 00818 } 00819 00825 Status setFrameBuffersAllocator(FrameAllocator* pAllocator) 00826 { 00827 if (!isValid()) 00828 { 00829 return STATUS_ERROR; 00830 } 00831 00832 if (pAllocator == NULL) 00833 { 00834 return (Status)oniStreamSetFrameBuffersAllocator(m_stream, NULL, NULL, NULL); 00835 } 00836 else 00837 { 00838 return (Status)oniStreamSetFrameBuffersAllocator(m_stream, pAllocator->allocateFrameBufferCallback, pAllocator->freeFrameBufferCallback, pAllocator); 00839 } 00840 } 00841 00846 OniStreamHandle _getHandle() const 00847 { 00848 return m_stream; 00849 } 00850 00855 CameraSettings* getCameraSettings() {return m_pCameraSettings;} 00856 00867 Status getProperty(int propertyId, void* data, int* dataSize) const 00868 { 00869 if (!isValid()) 00870 { 00871 return STATUS_ERROR; 00872 } 00873 00874 return (Status)oniStreamGetProperty(m_stream, propertyId, data, dataSize); 00875 } 00876 00887 Status setProperty(int propertyId, const void* data, int dataSize) 00888 { 00889 if (!isValid()) 00890 { 00891 return STATUS_ERROR; 00892 } 00893 00894 return (Status)oniStreamSetProperty(m_stream, propertyId, data, dataSize); 00895 } 00896 00903 VideoMode getVideoMode() const 00904 { 00905 VideoMode videoMode; 00906 getProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<OniVideoMode*>(&videoMode)); 00907 return videoMode; 00908 } 00909 00918 Status setVideoMode(const VideoMode& videoMode) 00919 { 00920 return setProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<const OniVideoMode&>(videoMode)); 00921 } 00922 00928 int getMaxPixelValue() const 00929 { 00930 int maxValue; 00931 Status rc = getProperty<int>(STREAM_PROPERTY_MAX_VALUE, &maxValue); 00932 if (rc != STATUS_OK) 00933 { 00934 return 0; 00935 } 00936 return maxValue; 00937 } 00938 00944 int getMinPixelValue() const 00945 { 00946 int minValue; 00947 Status rc = getProperty<int>(STREAM_PROPERTY_MIN_VALUE, &minValue); 00948 if (rc != STATUS_OK) 00949 { 00950 return 0; 00951 } 00952 return minValue; 00953 } 00954 00959 bool isCroppingSupported() const 00960 { 00961 return isPropertySupported(STREAM_PROPERTY_CROPPING); 00962 } 00963 00972 bool getCropping(int* pOriginX, int* pOriginY, int* pWidth, int* pHeight) const 00973 { 00974 OniCropping cropping; 00975 bool enabled = false; 00976 00977 Status rc = getProperty<OniCropping>(STREAM_PROPERTY_CROPPING, &cropping); 00978 00979 if (rc == STATUS_OK) 00980 { 00981 *pOriginX = cropping.originX; 00982 *pOriginY = cropping.originY; 00983 *pWidth = cropping.width; 00984 *pHeight = cropping.height; 00985 enabled = (cropping.enabled == TRUE); 00986 } 00987 00988 return enabled; 00989 } 00990 01000 Status setCropping(int originX, int originY, int width, int height) 01001 { 01002 OniCropping cropping; 01003 cropping.enabled = true; 01004 cropping.originX = originX; 01005 cropping.originY = originY; 01006 cropping.width = width; 01007 cropping.height = height; 01008 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping); 01009 } 01010 01015 Status resetCropping() 01016 { 01017 OniCropping cropping; 01018 cropping.enabled = false; 01019 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping); 01020 } 01021 01026 bool getMirroringEnabled() const 01027 { 01028 OniBool enabled; 01029 Status rc = getProperty<OniBool>(STREAM_PROPERTY_MIRRORING, &enabled); 01030 if (rc != STATUS_OK) 01031 { 01032 return false; 01033 } 01034 return enabled == TRUE; 01035 } 01036 01042 Status setMirroringEnabled(bool isEnabled) 01043 { 01044 return setProperty<OniBool>(STREAM_PROPERTY_MIRRORING, isEnabled ? TRUE : FALSE); 01045 } 01046 01051 float getHorizontalFieldOfView() const 01052 { 01053 float horizontal = 0; 01054 getProperty<float>(STREAM_PROPERTY_HORIZONTAL_FOV, &horizontal); 01055 return horizontal; 01056 } 01057 01062 float getVerticalFieldOfView() const 01063 { 01064 float vertical = 0; 01065 getProperty<float>(STREAM_PROPERTY_VERTICAL_FOV, &vertical); 01066 return vertical; 01067 } 01068 01078 template <class T> 01079 Status setProperty(int propertyId, const T& value) 01080 { 01081 return setProperty(propertyId, &value, sizeof(T)); 01082 } 01083 01093 template <class T> 01094 Status getProperty(int propertyId, T* value) const 01095 { 01096 int size = sizeof(T); 01097 return getProperty(propertyId, value, &size); 01098 } 01099 01105 bool isPropertySupported(int propertyId) const 01106 { 01107 if (!isValid()) 01108 { 01109 return false; 01110 } 01111 01112 return oniStreamIsPropertySupported(m_stream, propertyId) == TRUE; 01113 } 01114 01124 Status invoke(int commandId, void* data, int dataSize) 01125 { 01126 if (!isValid()) 01127 { 01128 return STATUS_ERROR; 01129 } 01130 01131 return (Status)oniStreamInvoke(m_stream, commandId, data, dataSize); 01132 } 01133 01143 template <class T> 01144 Status invoke(int commandId, T& value) 01145 { 01146 return invoke(commandId, &value, sizeof(T)); 01147 } 01148 01154 bool isCommandSupported(int commandId) const 01155 { 01156 if (!isValid()) 01157 { 01158 return false; 01159 } 01160 01161 return (Status)oniStreamIsCommandSupported(m_stream, commandId) == TRUE; 01162 } 01163 01164 private: 01165 friend class Device; 01166 01167 void _setHandle(OniStreamHandle stream) 01168 { 01169 m_sensorInfo._setInternal(NULL); 01170 m_stream = stream; 01171 01172 if (stream != NULL) 01173 { 01174 m_sensorInfo._setInternal(oniStreamGetSensorInfo(m_stream)); 01175 } 01176 } 01177 01178 private: 01179 VideoStream(const VideoStream& other); 01180 VideoStream& operator=(const VideoStream& other); 01181 01182 OniStreamHandle m_stream; 01183 SensorInfo m_sensorInfo; 01184 CameraSettings* m_pCameraSettings; 01185 bool m_isOwner; 01186 }; 01187 01204 class Device 01205 { 01206 public: 01211 Device() : m_pPlaybackControl(NULL), m_device(NULL), m_isOwner(true) 01212 { 01213 clearSensors(); 01214 } 01215 01220 explicit Device(OniDeviceHandle handle) : m_pPlaybackControl(NULL), m_device(NULL), m_isOwner(false) 01221 { 01222 _setHandle(handle); 01223 } 01224 01229 ~Device() 01230 { 01231 if (m_device != NULL) 01232 { 01233 close(); 01234 } 01235 } 01236 01266 inline Status open(const char* uri); 01267 01273 inline void close(); 01274 01284 const DeviceInfo& getDeviceInfo() const 01285 { 01286 return m_deviceInfo; 01287 } 01288 01296 bool hasSensor(SensorType sensorType) 01297 { 01298 int i; 01299 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01300 { 01301 if (m_aSensorInfo[i].getSensorType() == sensorType) 01302 { 01303 return true; 01304 } 01305 } 01306 01307 if (i == ONI_MAX_SENSORS) 01308 { 01309 return false; 01310 } 01311 01312 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01313 01314 if (pInfo == NULL) 01315 { 01316 return false; 01317 } 01318 01319 m_aSensorInfo[i]._setInternal(pInfo); 01320 01321 return true; 01322 } 01323 01331 const SensorInfo* getSensorInfo(SensorType sensorType) 01332 { 01333 int i; 01334 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01335 { 01336 if (m_aSensorInfo[i].getSensorType() == sensorType) 01337 { 01338 return &m_aSensorInfo[i]; 01339 } 01340 } 01341 01342 // not found. check to see we have additional space 01343 if (i == ONI_MAX_SENSORS) 01344 { 01345 return NULL; 01346 } 01347 01348 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01349 if (pInfo == NULL) 01350 { 01351 return NULL; 01352 } 01353 01354 m_aSensorInfo[i]._setInternal(pInfo); 01355 return &m_aSensorInfo[i]; 01356 } 01357 01362 OniDeviceHandle _getHandle() const 01363 { 01364 return m_device; 01365 } 01366 01371 PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;} 01372 01384 Status getProperty(int propertyId, void* data, int* dataSize) const 01385 { 01386 return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize); 01387 } 01388 01400 Status setProperty(int propertyId, const void* data, int dataSize) 01401 { 01402 return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize); 01403 } 01404 01412 bool isImageRegistrationModeSupported(ImageRegistrationMode mode) const 01413 { 01414 return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE); 01415 } 01416 01424 ImageRegistrationMode getImageRegistrationMode() const 01425 { 01426 ImageRegistrationMode mode; 01427 Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode); 01428 if (rc != STATUS_OK) 01429 { 01430 return IMAGE_REGISTRATION_OFF; 01431 } 01432 return mode; 01433 } 01434 01448 Status setImageRegistrationMode(ImageRegistrationMode mode) 01449 { 01450 return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode); 01451 } 01452 01457 bool isValid() const 01458 { 01459 return m_device != NULL; 01460 } 01461 01466 bool isFile() const 01467 { 01468 return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) && 01469 isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) && 01470 isCommandSupported(DEVICE_COMMAND_SEEK); 01471 } 01472 01481 Status setDepthColorSyncEnabled(bool isEnabled) 01482 { 01483 Status rc = STATUS_OK; 01484 01485 if (isEnabled) 01486 { 01487 rc = (Status)oniDeviceEnableDepthColorSync(m_device); 01488 } 01489 else 01490 { 01491 oniDeviceDisableDepthColorSync(m_device); 01492 } 01493 01494 return rc; 01495 } 01496 01497 bool getDepthColorSyncEnabled() 01498 { 01499 return oniDeviceGetDepthColorSyncEnabled(m_device) == TRUE; 01500 } 01501 01512 template <class T> 01513 Status setProperty(int propertyId, const T& value) 01514 { 01515 return setProperty(propertyId, &value, sizeof(T)); 01516 } 01517 01527 template <class T> 01528 Status getProperty(int propertyId, T* value) const 01529 { 01530 int size = sizeof(T); 01531 return getProperty(propertyId, value, &size); 01532 } 01533 01539 bool isPropertySupported(int propertyId) const 01540 { 01541 return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE; 01542 } 01543 01553 Status invoke(int commandId, void* data, int dataSize) 01554 { 01555 return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize); 01556 } 01557 01567 template <class T> 01568 Status invoke(int propertyId, T& value) 01569 { 01570 return invoke(propertyId, &value, sizeof(T)); 01571 } 01572 01578 bool isCommandSupported(int commandId) const 01579 { 01580 return oniDeviceIsCommandSupported(m_device, commandId) == TRUE; 01581 } 01582 01584 inline Status _openEx(const char* uri, const char* mode); 01585 01586 private: 01587 Device(const Device&); 01588 Device& operator=(const Device&); 01589 01590 void clearSensors() 01591 { 01592 for (int i = 0; i < ONI_MAX_SENSORS; ++i) 01593 { 01594 m_aSensorInfo[i]._setInternal(NULL); 01595 } 01596 } 01597 01598 inline Status _setHandle(OniDeviceHandle deviceHandle); 01599 01600 private: 01601 PlaybackControl* m_pPlaybackControl; 01602 01603 OniDeviceHandle m_device; 01604 DeviceInfo m_deviceInfo; 01605 SensorInfo m_aSensorInfo[ONI_MAX_SENSORS]; 01606 01607 bool m_isOwner; 01608 }; 01609 01623 class PlaybackControl 01624 { 01625 public: 01626 01632 ~PlaybackControl() 01633 { 01634 detach(); 01635 } 01636 01657 float getSpeed() const 01658 { 01659 if (!isValid()) 01660 { 01661 return 0.0f; 01662 } 01663 float speed; 01664 Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed); 01665 if (rc != STATUS_OK) 01666 { 01667 return 1.0f; 01668 } 01669 return speed; 01670 } 01678 Status setSpeed(float speed) 01679 { 01680 if (!isValid()) 01681 { 01682 return STATUS_NO_DEVICE; 01683 } 01684 return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed); 01685 } 01686 01692 bool getRepeatEnabled() const 01693 { 01694 if (!isValid()) 01695 { 01696 return false; 01697 } 01698 01699 OniBool repeat; 01700 Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat); 01701 if (rc != STATUS_OK) 01702 { 01703 return false; 01704 } 01705 01706 return repeat == TRUE; 01707 } 01708 01717 Status setRepeatEnabled(bool repeat) 01718 { 01719 if (!isValid()) 01720 { 01721 return STATUS_NO_DEVICE; 01722 } 01723 01724 return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE); 01725 } 01726 01737 Status seek(const VideoStream& stream, int frameIndex) 01738 { 01739 if (!isValid()) 01740 { 01741 return STATUS_NO_DEVICE; 01742 } 01743 OniSeek seek; 01744 seek.frameIndex = frameIndex; 01745 seek.stream = stream._getHandle(); 01746 return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek); 01747 } 01748 01757 int getNumberOfFrames(const VideoStream& stream) const 01758 { 01759 int numOfFrames = -1; 01760 Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames); 01761 if (rc != STATUS_OK) 01762 { 01763 return 0; 01764 } 01765 return numOfFrames; 01766 } 01767 01768 bool isValid() const 01769 { 01770 return m_pDevice != NULL; 01771 } 01772 private: 01773 Status attach(Device* device) 01774 { 01775 if (!device->isValid() || !device->isFile()) 01776 { 01777 return STATUS_ERROR; 01778 } 01779 01780 detach(); 01781 m_pDevice = device; 01782 01783 return STATUS_OK; 01784 } 01785 void detach() 01786 { 01787 m_pDevice = NULL; 01788 } 01789 01790 friend class Device; 01791 PlaybackControl(Device* pDevice) : m_pDevice(NULL) 01792 { 01793 if (pDevice != NULL) 01794 { 01795 attach(pDevice); 01796 } 01797 } 01798 01799 Device* m_pDevice; 01800 }; 01801 01802 class CameraSettings 01803 { 01804 public: 01805 // setters 01806 Status setAutoExposureEnabled(bool enabled) 01807 { 01808 return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE); 01809 } 01810 Status setAutoWhiteBalanceEnabled(bool enabled) 01811 { 01812 return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE); 01813 } 01814 01815 bool getAutoExposureEnabled() const 01816 { 01817 OniBool enabled = FALSE; 01818 01819 Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled); 01820 return rc == STATUS_OK && enabled == TRUE; 01821 } 01822 bool getAutoWhiteBalanceEnabled() const 01823 { 01824 OniBool enabled = FALSE; 01825 01826 Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled); 01827 return rc == STATUS_OK && enabled == TRUE; 01828 } 01829 01830 Status setGain(int gain) 01831 { 01832 return setProperty(STREAM_PROPERTY_GAIN, gain); 01833 } 01834 Status setExposure(int exposure) 01835 { 01836 return setProperty(STREAM_PROPERTY_EXPOSURE, exposure); 01837 } 01838 int getGain() 01839 { 01840 int gain; 01841 Status rc = getProperty(STREAM_PROPERTY_GAIN, &gain); 01842 if (rc != STATUS_OK) 01843 { 01844 return 100; 01845 } 01846 return gain; 01847 } 01848 int getExposure() 01849 { 01850 int exposure; 01851 Status rc = getProperty(STREAM_PROPERTY_EXPOSURE, &exposure); 01852 if (rc != STATUS_OK) 01853 { 01854 return 0; 01855 } 01856 return exposure; 01857 } 01858 01859 bool isValid() const {return m_pStream != NULL;} 01860 private: 01861 template <class T> 01862 Status getProperty(int propertyId, T* value) const 01863 { 01864 if (!isValid()) return STATUS_NOT_SUPPORTED; 01865 01866 return m_pStream->getProperty<T>(propertyId, value); 01867 } 01868 template <class T> 01869 Status setProperty(int propertyId, const T& value) 01870 { 01871 if (!isValid()) return STATUS_NOT_SUPPORTED; 01872 01873 return m_pStream->setProperty<T>(propertyId, value); 01874 } 01875 01876 friend class VideoStream; 01877 CameraSettings(VideoStream* pStream) 01878 { 01879 m_pStream = pStream; 01880 } 01881 01882 VideoStream* m_pStream; 01883 }; 01884 01885 01898 class OpenNI 01899 { 01900 public: 01901 01917 class DeviceConnectedListener 01918 { 01919 public: 01920 DeviceConnectedListener() 01921 { 01922 m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback; 01923 m_deviceConnectedCallbacks.deviceDisconnected = NULL; 01924 m_deviceConnectedCallbacks.deviceStateChanged = NULL; 01925 m_deviceConnectedCallbacksHandle = NULL; 01926 } 01927 01928 virtual ~DeviceConnectedListener() 01929 { 01930 } 01931 01943 virtual void onDeviceConnected(const DeviceInfo*) = 0; 01944 private: 01945 static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01946 { 01947 DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie; 01948 pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo)); 01949 } 01950 01951 friend class OpenNI; 01952 OniDeviceCallbacks m_deviceConnectedCallbacks; 01953 OniCallbackHandle m_deviceConnectedCallbacksHandle; 01954 01955 }; 01972 class DeviceDisconnectedListener 01973 { 01974 public: 01975 DeviceDisconnectedListener() 01976 { 01977 m_deviceDisconnectedCallbacks.deviceConnected = NULL; 01978 m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback; 01979 m_deviceDisconnectedCallbacks.deviceStateChanged = NULL; 01980 m_deviceDisconnectedCallbacksHandle = NULL; 01981 } 01982 01983 virtual ~DeviceDisconnectedListener() 01984 { 01985 } 01986 01995 virtual void onDeviceDisconnected(const DeviceInfo*) = 0; 01996 private: 01997 static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01998 { 01999 DeviceDisconnectedListener* pListener = (DeviceDisconnectedListener*)pCookie; 02000 pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo)); 02001 } 02002 02003 friend class OpenNI; 02004 OniDeviceCallbacks m_deviceDisconnectedCallbacks; 02005 OniCallbackHandle m_deviceDisconnectedCallbacksHandle; 02006 }; 02020 class DeviceStateChangedListener 02021 { 02022 public: 02023 DeviceStateChangedListener() 02024 { 02025 m_deviceStateChangedCallbacks.deviceConnected = NULL; 02026 m_deviceStateChangedCallbacks.deviceDisconnected = NULL; 02027 m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback; 02028 m_deviceStateChangedCallbacksHandle = NULL; 02029 } 02030 02031 virtual ~DeviceStateChangedListener() 02032 { 02033 } 02034 02041 virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0; 02042 private: 02043 static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie) 02044 { 02045 DeviceStateChangedListener* pListener = (DeviceStateChangedListener*)pCookie; 02046 pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state)); 02047 } 02048 02049 friend class OpenNI; 02050 OniDeviceCallbacks m_deviceStateChangedCallbacks; 02051 OniCallbackHandle m_deviceStateChangedCallbacksHandle; 02052 }; 02053 02059 static Status initialize() 02060 { 02061 return (Status)oniInitialize(ONI_API_VERSION); // provide version of API, to make sure proper struct sizes are used 02062 } 02063 02068 static void shutdown() 02069 { 02070 oniShutdown(); 02071 } 02072 02076 static Version getVersion() 02077 { 02078 OniVersion version = oniGetVersion(); 02079 union 02080 { 02081 OniVersion* pC; 02082 Version* pCpp; 02083 } a; 02084 a.pC = &version; 02085 return *a.pCpp; 02086 } 02087 02095 static const char* getExtendedError() 02096 { 02097 return oniGetExtendedError(); 02098 } 02099 02104 static void enumerateDevices(Array<DeviceInfo>* deviceInfoList) 02105 { 02106 OniDeviceInfo* m_pDeviceInfos; 02107 int m_deviceInfoCount; 02108 oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount); 02109 deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true); 02110 oniReleaseDeviceList(m_pDeviceInfos); 02111 } 02112 02121 static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER) 02122 { 02123 static const int ONI_MAX_STREAMS = 50; 02124 OniStreamHandle streams[ONI_MAX_STREAMS]; 02125 02126 if (streamCount > ONI_MAX_STREAMS) 02127 { 02128 printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS); 02129 return STATUS_BAD_PARAMETER; 02130 } 02131 02132 *pReadyStreamIndex = -1; 02133 for (int i = 0; i < streamCount; ++i) 02134 { 02135 if (pStreams[i] != NULL) 02136 { 02137 streams[i] = pStreams[i]->_getHandle(); 02138 } 02139 else 02140 { 02141 streams[i] = NULL; 02142 } 02143 } 02144 Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout); 02145 02146 return rc; 02147 } 02148 02156 static Status addDeviceConnectedListener(DeviceConnectedListener* pListener) 02157 { 02158 if (pListener->m_deviceConnectedCallbacksHandle != NULL) 02159 { 02160 return STATUS_ERROR; 02161 } 02162 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle); 02163 } 02171 static Status addDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02172 { 02173 if (pListener->m_deviceDisconnectedCallbacksHandle != NULL) 02174 { 02175 return STATUS_ERROR; 02176 } 02177 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle); 02178 } 02186 static Status addDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02187 { 02188 if (pListener->m_deviceStateChangedCallbacksHandle != NULL) 02189 { 02190 return STATUS_ERROR; 02191 } 02192 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle); 02193 } 02201 static void removeDeviceConnectedListener(DeviceConnectedListener* pListener) 02202 { 02203 oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle); 02204 pListener->m_deviceConnectedCallbacksHandle = NULL; 02205 } 02213 static void removeDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02214 { 02215 oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle); 02216 pListener->m_deviceDisconnectedCallbacksHandle = NULL; 02217 } 02225 static void removeDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02226 { 02227 oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle); 02228 pListener->m_deviceStateChangedCallbacksHandle = NULL; 02229 } 02230 02239 static OniStatus setLogOutputFolder(const char *strLogOutputFolder) 02240 { 02241 return oniSetLogOutputFolder(strLogOutputFolder); 02242 } 02243 02253 static OniStatus getLogFileName(char *strFileName, int nBufferSize) 02254 { 02255 return oniGetLogFileName(strFileName, nBufferSize); 02256 } 02257 02267 static OniStatus setLogMinSeverity(int nMinSeverity) 02268 { 02269 return oniSetLogMinSeverity(nMinSeverity); 02270 } 02271 02280 static OniStatus setLogConsoleOutput(bool bConsoleOutput) 02281 { 02282 return oniSetLogConsoleOutput(bConsoleOutput); 02283 } 02284 02293 static OniStatus setLogFileOutput(bool bFileOutput) 02294 { 02295 return oniSetLogFileOutput(bFileOutput); 02296 } 02297 02298 #if ONI_PLATFORM == ONI_PLATFORM_ANDROID_ARM 02299 02308 static OniStatus setLogAndroidOutput(bool bAndroidOutput) 02309 { 02310 return oniSetLogAndroidOutput(bAndroidOutput); 02311 } 02312 #endif 02313 02314 private: 02315 OpenNI() 02316 { 02317 } 02318 }; 02319 02355 class CoordinateConverter 02356 { 02357 public: 02368 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ) 02369 { 02370 float depthX, depthY, depthZ; 02371 Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ); 02372 *pDepthX = (int)depthX; 02373 *pDepthY = (int)depthY; 02374 *pDepthZ = (DepthPixel)depthZ; 02375 return rc; 02376 } 02377 02388 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ) 02389 { 02390 return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ); 02391 } 02392 02403 static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02404 { 02405 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ); 02406 } 02407 02418 static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02419 { 02420 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ); 02421 } 02422 02434 static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY) 02435 { 02436 return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY); 02437 } 02438 }; 02439 02454 class Recorder 02455 { 02456 public: 02461 Recorder() : m_recorder(NULL) 02462 { 02463 } 02464 02468 ~Recorder() 02469 { 02470 destroy(); 02471 } 02472 02484 Status create(const char* fileName) 02485 { 02486 if (!isValid()) 02487 { 02488 return (Status)oniCreateRecorder(fileName, &m_recorder); 02489 } 02490 return STATUS_ERROR; 02491 } 02492 02499 bool isValid() const 02500 { 02501 return NULL != getHandle(); 02502 } 02503 02514 Status attach(VideoStream& stream, bool allowLossyCompression = false) 02515 { 02516 if (!isValid() || !stream.isValid()) 02517 { 02518 return STATUS_ERROR; 02519 } 02520 return (Status)oniRecorderAttachStream( 02521 m_recorder, 02522 stream._getHandle(), 02523 allowLossyCompression); 02524 } 02525 02532 Status start() 02533 { 02534 if (!isValid()) 02535 { 02536 return STATUS_ERROR; 02537 } 02538 return (Status)oniRecorderStart(m_recorder); 02539 } 02540 02544 void stop() 02545 { 02546 if (isValid()) 02547 { 02548 oniRecorderStop(m_recorder); 02549 } 02550 } 02551 02555 void destroy() 02556 { 02557 if (isValid()) 02558 { 02559 oniRecorderDestroy(&m_recorder); 02560 } 02561 } 02562 02563 private: 02564 Recorder(const Recorder&); 02565 Recorder& operator=(const Recorder&); 02566 02570 OniRecorderHandle getHandle() const 02571 { 02572 return m_recorder; 02573 } 02574 02575 02576 OniRecorderHandle m_recorder; 02577 }; 02578 02579 // Implemetation 02580 Status VideoStream::create(const Device& device, SensorType sensorType) 02581 { 02582 OniStreamHandle streamHandle; 02583 Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle); 02584 if (rc != STATUS_OK) 02585 { 02586 return rc; 02587 } 02588 02589 m_isOwner = true; 02590 _setHandle(streamHandle); 02591 02592 if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE)) 02593 { 02594 m_pCameraSettings = new CameraSettings(this); 02595 } 02596 02597 return STATUS_OK; 02598 } 02599 02600 void VideoStream::destroy() 02601 { 02602 if (!isValid()) 02603 { 02604 return; 02605 } 02606 02607 if (m_pCameraSettings != NULL) 02608 { 02609 delete m_pCameraSettings; 02610 m_pCameraSettings = NULL; 02611 } 02612 02613 if (m_stream != NULL) 02614 { 02615 if(m_isOwner) 02616 oniStreamDestroy(m_stream); 02617 m_stream = NULL; 02618 } 02619 } 02620 02621 Status Device::open(const char* uri) 02622 { 02623 //If we are not the owners, we stick with our own device 02624 if(!m_isOwner) 02625 { 02626 if(isValid()){ 02627 return STATUS_OK; 02628 }else{ 02629 return STATUS_OUT_OF_FLOW; 02630 } 02631 } 02632 02633 OniDeviceHandle deviceHandle; 02634 Status rc = (Status)oniDeviceOpen(uri, &deviceHandle); 02635 if (rc != STATUS_OK) 02636 { 02637 return rc; 02638 } 02639 02640 _setHandle(deviceHandle); 02641 02642 return STATUS_OK; 02643 } 02644 02645 Status Device::_openEx(const char* uri, const char* mode) 02646 { 02647 //If we are not the owners, we stick with our own device 02648 if(!m_isOwner) 02649 { 02650 if(isValid()){ 02651 return STATUS_OK; 02652 }else{ 02653 return STATUS_OUT_OF_FLOW; 02654 } 02655 } 02656 02657 OniDeviceHandle deviceHandle; 02658 Status rc = (Status)oniDeviceOpenEx(uri, mode, &deviceHandle); 02659 if (rc != STATUS_OK) 02660 { 02661 return rc; 02662 } 02663 02664 _setHandle(deviceHandle); 02665 02666 return STATUS_OK; 02667 } 02668 02669 Status Device::_setHandle(OniDeviceHandle deviceHandle) 02670 { 02671 if (m_device == NULL) 02672 { 02673 m_device = deviceHandle; 02674 02675 clearSensors(); 02676 02677 oniDeviceGetInfo(m_device, &m_deviceInfo); 02678 02679 if (isFile()) 02680 { 02681 m_pPlaybackControl = new PlaybackControl(this); 02682 } 02683 02684 // Read deviceInfo 02685 return STATUS_OK; 02686 } 02687 02688 return STATUS_OUT_OF_FLOW; 02689 } 02690 02691 void Device::close() 02692 { 02693 if (m_pPlaybackControl != NULL) 02694 { 02695 delete m_pPlaybackControl; 02696 m_pPlaybackControl = NULL; 02697 } 02698 02699 if (m_device != NULL) 02700 { 02701 if(m_isOwner) 02702 { 02703 oniDeviceClose(m_device); 02704 } 02705 02706 m_device = NULL; 02707 } 02708 } 02709 02710 02711 } 02712 02713 #endif // _OPEN_NI_HPP_