![]() |
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 00156 class VideoMode : private OniVideoMode 00157 { 00158 public: 00164 VideoMode() 00165 {} 00166 00172 VideoMode(const VideoMode& other) 00173 { 00174 *this = other; 00175 } 00176 00183 VideoMode& operator=(const VideoMode& other) 00184 { 00185 setPixelFormat(other.getPixelFormat()); 00186 setResolution(other.getResolutionX(), other.getResolutionY()); 00187 setFps(other.getFps()); 00188 00189 return *this; 00190 } 00191 00196 PixelFormat getPixelFormat() const { return (PixelFormat)pixelFormat; } 00197 00202 int getResolutionX() const { return resolutionX; } 00203 00208 int getResolutionY() const {return resolutionY;} 00209 00214 int getFps() const { return fps; } 00215 00222 void setPixelFormat(PixelFormat format) { this->pixelFormat = (OniPixelFormat)format; } 00223 00231 void setResolution(int resolutionX, int resolutionY) 00232 { 00233 this->resolutionX = resolutionX; 00234 this->resolutionY = resolutionY; 00235 } 00236 00243 void setFps(int fps) { this->fps = fps; } 00244 00245 friend class SensorInfo; 00246 friend class VideoStream; 00247 friend class VideoFrameRef; 00248 }; 00249 00267 class SensorInfo 00268 { 00269 public: 00274 SensorType getSensorType() const { return (SensorType)m_pInfo->sensorType; } 00275 00283 const Array<VideoMode>& getSupportedVideoModes() const { return m_videoModes; } 00284 00285 private: 00286 SensorInfo(const SensorInfo&); 00287 SensorInfo& operator=(const SensorInfo&); 00288 00289 SensorInfo() : m_pInfo(NULL), m_videoModes(NULL, 0) {} 00290 00291 SensorInfo(const OniSensorInfo* pInfo) : m_pInfo(NULL), m_videoModes(NULL, 0) 00292 { 00293 _setInternal(pInfo); 00294 } 00295 00296 void _setInternal(const OniSensorInfo* pInfo) 00297 { 00298 m_pInfo = pInfo; 00299 if (pInfo == NULL) 00300 { 00301 m_videoModes._setData(NULL, 0); 00302 } 00303 else 00304 { 00305 m_videoModes._setData(static_cast<VideoMode*>(pInfo->pSupportedVideoModes), pInfo->numSupportedVideoModes); 00306 } 00307 } 00308 00309 const OniSensorInfo* m_pInfo; 00310 Array<VideoMode> m_videoModes; 00311 00312 friend class VideoStream; 00313 friend class Device; 00314 }; 00315 00325 class DeviceInfo : private OniDeviceInfo 00326 { 00327 public: 00332 const char* getUri() const { return uri; } 00334 const char* getVendor() const { return vendor; } 00336 const char* getName() const { return name; } 00338 uint16_t getUsbVendorId() const { return usbVendorId; } 00340 uint16_t getUsbProductId() const { return usbProductId; } 00341 00342 friend class Device; 00343 friend class OpenNI; 00344 }; 00345 00359 class VideoFrameRef 00360 { 00361 public: 00366 VideoFrameRef() 00367 { 00368 m_pFrame = NULL; 00369 } 00370 00374 ~VideoFrameRef() 00375 { 00376 release(); 00377 } 00378 00384 VideoFrameRef(const VideoFrameRef& other) : m_pFrame(NULL) 00385 { 00386 _setFrame(other.m_pFrame); 00387 } 00388 00394 VideoFrameRef& operator=(const VideoFrameRef& other) 00395 { 00396 _setFrame(other.m_pFrame); 00397 return *this; 00398 } 00399 00405 inline int getDataSize() const 00406 { 00407 return m_pFrame->dataSize; 00408 } 00409 00415 inline const void* getData() const 00416 { 00417 return m_pFrame->data; 00418 } 00419 00426 inline SensorType getSensorType() const 00427 { 00428 return (SensorType)m_pFrame->sensorType; 00429 } 00430 00438 inline const VideoMode& getVideoMode() const 00439 { 00440 return static_cast<const VideoMode&>(m_pFrame->videoMode); 00441 } 00442 00450 inline uint64_t getTimestamp() const 00451 { 00452 return m_pFrame->timestamp; 00453 } 00454 00465 inline int getFrameIndex() const 00466 { 00467 return m_pFrame->frameIndex; 00468 } 00469 00476 inline int getWidth() const 00477 { 00478 return m_pFrame->width; 00479 } 00480 00486 inline int getHeight() const 00487 { 00488 return m_pFrame->height; 00489 } 00490 00495 inline bool getCroppingEnabled() const 00496 { 00497 return m_pFrame->croppingEnabled == TRUE; 00498 } 00499 00504 inline int getCropOriginX() const 00505 { 00506 return m_pFrame->cropOriginX; 00507 } 00508 00513 inline int getCropOriginY() const 00514 { 00515 return m_pFrame->cropOriginY; 00516 } 00517 00523 inline int getStrideInBytes() const 00524 { 00525 return m_pFrame->stride; 00526 } 00527 00531 inline bool isValid() const 00532 { 00533 return m_pFrame != NULL; 00534 } 00535 00540 void release() 00541 { 00542 if (m_pFrame != NULL) 00543 { 00544 oniFrameRelease(m_pFrame); 00545 m_pFrame = NULL; 00546 } 00547 } 00548 00550 void _setFrame(OniFrame* pFrame) 00551 { 00552 setReference(pFrame); 00553 if (pFrame != NULL) 00554 { 00555 oniFrameAddRef(pFrame); 00556 } 00557 } 00558 00560 OniFrame* _getFrame() 00561 { 00562 return m_pFrame; 00563 } 00564 00565 private: 00566 friend class VideoStream; 00567 inline void setReference(OniFrame* pFrame) 00568 { 00569 // Initial - don't addref. This is the reference from OpenNI 00570 release(); 00571 m_pFrame = pFrame; 00572 } 00573 00574 OniFrame* m_pFrame; // const!!? 00575 }; 00576 00577 00578 class Device; 00579 00601 class CameraSettings; 00602 00603 class VideoStream 00604 { 00605 public: 00613 class NewFrameListener 00614 { 00615 public: 00619 NewFrameListener() : m_callbackHandle(NULL) 00620 { 00621 } 00622 00626 virtual void onNewFrame(VideoStream&) = 0; 00627 00628 private: 00629 friend class VideoStream; 00630 00631 static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie) 00632 { 00633 NewFrameListener* pListener = (NewFrameListener*)pCookie; 00634 VideoStream stream; 00635 stream._setHandle(streamHandle); 00636 pListener->onNewFrame(stream); 00637 stream._setHandle(NULL); 00638 } 00639 OniCallbackHandle m_callbackHandle; 00640 }; 00641 00646 VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL) 00647 {} 00648 00653 ~VideoStream() 00654 { 00655 destroy(); 00656 } 00657 00662 bool isValid() const 00663 { 00664 return m_stream != NULL; 00665 } 00666 00676 inline Status create(const Device& device, SensorType sensorType); 00677 00683 inline void destroy(); 00684 00693 const SensorInfo& getSensorInfo() const 00694 { 00695 return m_sensorInfo; 00696 } 00697 00701 Status start() 00702 { 00703 if (!isValid()) 00704 { 00705 return STATUS_ERROR; 00706 } 00707 00708 return (Status)oniStreamStart(m_stream); 00709 } 00710 00714 void stop() 00715 { 00716 if (!isValid()) 00717 { 00718 return; 00719 } 00720 00721 oniStreamStop(m_stream); 00722 } 00723 00734 Status readFrame(VideoFrameRef* pFrame) 00735 { 00736 if (!isValid()) 00737 { 00738 return STATUS_ERROR; 00739 } 00740 00741 OniFrame* pOniFrame; 00742 Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame); 00743 00744 pFrame->setReference(pOniFrame); 00745 return rc; 00746 } 00747 00755 Status addNewFrameListener(NewFrameListener* pListener) 00756 { 00757 if (!isValid()) 00758 { 00759 return STATUS_ERROR; 00760 } 00761 if (pListener->m_callbackHandle != NULL) 00762 { 00763 return STATUS_ERROR; 00764 } 00765 00766 return (Status)oniStreamRegisterNewFrameCallback(m_stream, pListener->callback, pListener, &pListener->m_callbackHandle); 00767 } 00768 00773 void removeNewFrameListener(NewFrameListener* pListener) 00774 { 00775 if (!isValid()) 00776 { 00777 return; 00778 } 00779 00780 oniStreamUnregisterNewFrameCallback(m_stream, pListener->m_callbackHandle); 00781 pListener->m_callbackHandle = NULL; 00782 } 00783 00788 OniStreamHandle _getHandle() const 00789 { 00790 return m_stream; 00791 } 00792 00797 CameraSettings* getCameraSettings() {return m_pCameraSettings;} 00798 00809 Status getProperty(int propertyId, void* data, int* dataSize) const 00810 { 00811 if (!isValid()) 00812 { 00813 return STATUS_ERROR; 00814 } 00815 00816 return (Status)oniStreamGetProperty(m_stream, propertyId, data, dataSize); 00817 } 00818 00829 Status setProperty(int propertyId, const void* data, int dataSize) 00830 { 00831 if (!isValid()) 00832 { 00833 return STATUS_ERROR; 00834 } 00835 00836 return (Status)oniStreamSetProperty(m_stream, propertyId, data, dataSize); 00837 } 00838 00845 VideoMode getVideoMode() const 00846 { 00847 VideoMode videoMode; 00848 getProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<OniVideoMode*>(&videoMode)); 00849 return videoMode; 00850 } 00851 00860 Status setVideoMode(const VideoMode& videoMode) 00861 { 00862 return setProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<const OniVideoMode&>(videoMode)); 00863 } 00864 00870 int getMaxPixelValue() const 00871 { 00872 int maxValue; 00873 Status rc = getProperty<int>(STREAM_PROPERTY_MAX_VALUE, &maxValue); 00874 if (rc != STATUS_OK) 00875 { 00876 return 0; 00877 } 00878 return maxValue; 00879 } 00880 00886 int getMinPixelValue() const 00887 { 00888 int minValue; 00889 Status rc = getProperty<int>(STREAM_PROPERTY_MIN_VALUE, &minValue); 00890 if (rc != STATUS_OK) 00891 { 00892 return 0; 00893 } 00894 return minValue; 00895 } 00896 00901 bool isCroppingSupported() const 00902 { 00903 return isPropertySupported(STREAM_PROPERTY_CROPPING); 00904 } 00905 00914 bool getCropping(int* pOriginX, int* pOriginY, int* pWidth, int* pHeight) const 00915 { 00916 OniCropping cropping; 00917 bool enabled = false; 00918 00919 Status rc = getProperty<OniCropping>(STREAM_PROPERTY_CROPPING, &cropping); 00920 00921 if (rc == STATUS_OK) 00922 { 00923 *pOriginX = cropping.originX; 00924 *pOriginY = cropping.originY; 00925 *pWidth = cropping.width; 00926 *pHeight = cropping.height; 00927 enabled = (cropping.enabled == TRUE); 00928 } 00929 00930 return enabled; 00931 } 00932 00942 Status setCropping(int originX, int originY, int width, int height) 00943 { 00944 OniCropping cropping; 00945 cropping.enabled = true; 00946 cropping.originX = originX; 00947 cropping.originY = originY; 00948 cropping.width = width; 00949 cropping.height = height; 00950 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping); 00951 } 00952 00957 Status resetCropping() 00958 { 00959 OniCropping cropping; 00960 cropping.enabled = false; 00961 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping); 00962 } 00963 00968 bool getMirroringEnabled() const 00969 { 00970 OniBool enabled; 00971 Status rc = getProperty<OniBool>(STREAM_PROPERTY_MIRRORING, &enabled); 00972 if (rc != STATUS_OK) 00973 { 00974 return false; 00975 } 00976 return enabled == TRUE; 00977 } 00978 00984 Status setMirroringEnabled(bool isEnabled) 00985 { 00986 return setProperty<OniBool>(STREAM_PROPERTY_MIRRORING, isEnabled ? TRUE : FALSE); 00987 } 00988 00993 float getHorizontalFieldOfView() const 00994 { 00995 float horizontal = 0; 00996 getProperty<float>(STREAM_PROPERTY_HORIZONTAL_FOV, &horizontal); 00997 return horizontal; 00998 } 00999 01004 float getVerticalFieldOfView() const 01005 { 01006 float vertical = 0; 01007 getProperty<float>(STREAM_PROPERTY_VERTICAL_FOV, &vertical); 01008 return vertical; 01009 } 01010 01020 template <class T> 01021 Status setProperty(int propertyId, const T& value) 01022 { 01023 return setProperty(propertyId, &value, sizeof(T)); 01024 } 01025 01035 template <class T> 01036 Status getProperty(int propertyId, T* value) const 01037 { 01038 int size = sizeof(T); 01039 return getProperty(propertyId, value, &size); 01040 } 01041 01047 bool isPropertySupported(int propertyId) const 01048 { 01049 if (!isValid()) 01050 { 01051 return false; 01052 } 01053 01054 return oniStreamIsPropertySupported(m_stream, propertyId) == TRUE; 01055 } 01056 01066 Status invoke(int commandId, void* data, int dataSize) 01067 { 01068 if (!isValid()) 01069 { 01070 return STATUS_ERROR; 01071 } 01072 01073 return (Status)oniStreamInvoke(m_stream, commandId, data, dataSize); 01074 } 01075 01085 template <class T> 01086 Status invoke(int commandId, const T& value) 01087 { 01088 return invoke(commandId, &value, sizeof(T)); 01089 } 01090 01096 bool isCommandSupported(int commandId) const 01097 { 01098 if (!isValid()) 01099 { 01100 return false; 01101 } 01102 01103 return (Status)oniStreamIsCommandSupported(m_stream, commandId) == TRUE; 01104 } 01105 01106 private: 01107 friend class Device; 01108 01109 void _setHandle(OniStreamHandle stream) 01110 { 01111 m_sensorInfo._setInternal(NULL); 01112 m_stream = stream; 01113 01114 if (stream != NULL) 01115 { 01116 m_sensorInfo._setInternal(oniStreamGetSensorInfo(m_stream)); 01117 } 01118 } 01119 01120 private: 01121 VideoStream(const VideoStream& other); 01122 VideoStream& operator=(const VideoStream& other); 01123 01124 OniStreamHandle m_stream; 01125 SensorInfo m_sensorInfo; 01126 CameraSettings* m_pCameraSettings; 01127 }; 01128 01129 class PlaybackControl; 01130 01147 class Device 01148 { 01149 public: 01154 Device() : m_pPlaybackControl(NULL), m_device(NULL) 01155 { 01156 clearSensors(); 01157 } 01158 01163 ~Device() 01164 { 01165 if (m_device != NULL) 01166 { 01167 close(); 01168 } 01169 } 01170 01200 inline Status open(const char* uri); 01201 01207 inline void close(); 01208 01218 const DeviceInfo& getDeviceInfo() const 01219 { 01220 return m_deviceInfo; 01221 } 01222 01230 bool hasSensor(SensorType sensorType) 01231 { 01232 int i; 01233 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01234 { 01235 if (m_aSensorInfo[i].getSensorType() == sensorType) 01236 { 01237 return true; 01238 } 01239 } 01240 01241 if (i == ONI_MAX_SENSORS) 01242 { 01243 return false; 01244 } 01245 01246 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01247 01248 if (pInfo == NULL) 01249 { 01250 return false; 01251 } 01252 01253 m_aSensorInfo[i]._setInternal(pInfo); 01254 01255 return true; 01256 } 01257 01265 const SensorInfo* getSensorInfo(SensorType sensorType) 01266 { 01267 int i; 01268 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01269 { 01270 if (m_aSensorInfo[i].getSensorType() == sensorType) 01271 { 01272 return &m_aSensorInfo[i]; 01273 } 01274 } 01275 01276 // not found. check to see we have additional space 01277 if (i == ONI_MAX_SENSORS) 01278 { 01279 return NULL; 01280 } 01281 01282 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01283 if (pInfo == NULL) 01284 { 01285 return NULL; 01286 } 01287 01288 m_aSensorInfo[i]._setInternal(pInfo); 01289 return &m_aSensorInfo[i]; 01290 } 01291 01296 OniDeviceHandle _getHandle() const 01297 { 01298 return m_device; 01299 } 01300 01305 PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;} 01306 01318 Status getProperty(int propertyId, void* data, int* dataSize) const 01319 { 01320 return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize); 01321 } 01322 01334 Status setProperty(int propertyId, const void* data, int dataSize) 01335 { 01336 return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize); 01337 } 01338 01346 bool isImageRegistrationModeSupported(ImageRegistrationMode mode) const 01347 { 01348 return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE); 01349 } 01350 01358 ImageRegistrationMode getImageRegistrationMode() const 01359 { 01360 ImageRegistrationMode mode; 01361 Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode); 01362 if (rc != STATUS_OK) 01363 { 01364 return IMAGE_REGISTRATION_OFF; 01365 } 01366 return mode; 01367 } 01368 01382 Status setImageRegistrationMode(ImageRegistrationMode mode) 01383 { 01384 return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode); 01385 } 01386 01391 bool isValid() const 01392 { 01393 return m_device != NULL; 01394 } 01395 01400 bool isFile() const 01401 { 01402 return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) && 01403 isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) && 01404 isCommandSupported(DEVICE_COMMAND_SEEK); 01405 } 01406 01415 Status setDepthColorSyncEnabled(bool isEnabled) 01416 { 01417 Status rc = STATUS_OK; 01418 01419 if (isEnabled) 01420 { 01421 rc = (Status)oniDeviceEnableDepthColorSync(m_device); 01422 } 01423 else 01424 { 01425 oniDeviceDisableDepthColorSync(m_device); 01426 } 01427 01428 return rc; 01429 } 01430 01441 template <class T> 01442 Status setProperty(int propertyId, const T& value) 01443 { 01444 return setProperty(propertyId, &value, sizeof(T)); 01445 } 01446 01456 template <class T> 01457 Status getProperty(int propertyId, T* value) const 01458 { 01459 int size = sizeof(T); 01460 return getProperty(propertyId, value, &size); 01461 } 01462 01468 bool isPropertySupported(int propertyId) const 01469 { 01470 return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE; 01471 } 01472 01482 Status invoke(int commandId, const void* data, int dataSize) 01483 { 01484 return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize); 01485 } 01486 01496 template <class T> 01497 Status invoke(int propertyId, const T& value) 01498 { 01499 return invoke(propertyId, &value, sizeof(T)); 01500 } 01501 01507 bool isCommandSupported(int commandId) const 01508 { 01509 return oniDeviceIsCommandSupported(m_device, commandId) == TRUE; 01510 } 01511 01512 private: 01513 Device(const Device&); 01514 Device& operator=(const Device&); 01515 01516 void clearSensors() 01517 { 01518 for (int i = 0; i < ONI_MAX_SENSORS; ++i) 01519 { 01520 m_aSensorInfo[i]._setInternal(NULL); 01521 } 01522 } 01523 01524 Status _setHandle(OniDeviceHandle deviceHandle) 01525 { 01526 if (m_device == NULL) 01527 { 01528 m_device = deviceHandle; 01529 01530 clearSensors(); 01531 01532 oniDeviceGetInfo(m_device, &m_deviceInfo); 01533 // Read deviceInfo 01534 return STATUS_OK; 01535 } 01536 01537 return STATUS_OUT_OF_FLOW; 01538 } 01539 01540 private: 01541 PlaybackControl* m_pPlaybackControl; 01542 01543 OniDeviceHandle m_device; 01544 DeviceInfo m_deviceInfo; 01545 SensorInfo m_aSensorInfo[ONI_MAX_SENSORS]; 01546 }; 01547 01561 class PlaybackControl 01562 { 01563 public: 01564 01570 ~PlaybackControl() 01571 { 01572 detach(); 01573 } 01574 01595 float getSpeed() const 01596 { 01597 if (!isValid()) 01598 { 01599 return 0.0f; 01600 } 01601 float speed; 01602 Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed); 01603 if (rc != STATUS_OK) 01604 { 01605 return 1.0f; 01606 } 01607 return speed; 01608 } 01616 Status setSpeed(float speed) 01617 { 01618 if (!isValid()) 01619 { 01620 return STATUS_NO_DEVICE; 01621 } 01622 return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed); 01623 } 01624 01630 bool getRepeatEnabled() const 01631 { 01632 if (!isValid()) 01633 { 01634 return false; 01635 } 01636 01637 OniBool repeat; 01638 Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat); 01639 if (rc != STATUS_OK) 01640 { 01641 return false; 01642 } 01643 01644 return repeat == TRUE; 01645 } 01646 01655 Status setRepeatEnabled(bool repeat) 01656 { 01657 if (!isValid()) 01658 { 01659 return STATUS_NO_DEVICE; 01660 } 01661 01662 return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE); 01663 } 01664 01675 Status seek(const VideoStream& stream, int frameIndex) 01676 { 01677 if (!isValid()) 01678 { 01679 return STATUS_NO_DEVICE; 01680 } 01681 OniSeek seek; 01682 seek.frameIndex = frameIndex; 01683 seek.stream = stream._getHandle(); 01684 return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek); 01685 } 01686 01695 int getNumberOfFrames(const VideoStream& stream) const 01696 { 01697 int numOfFrames = -1; 01698 Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames); 01699 if (rc != STATUS_OK) 01700 { 01701 return 0; 01702 } 01703 return numOfFrames; 01704 } 01705 01706 bool isValid() const 01707 { 01708 return m_pDevice != NULL; 01709 } 01710 private: 01711 Status attach(Device* device) 01712 { 01713 if (!device->isValid() || !device->isFile()) 01714 { 01715 return STATUS_ERROR; 01716 } 01717 01718 detach(); 01719 m_pDevice = device; 01720 01721 return STATUS_OK; 01722 } 01723 void detach() 01724 { 01725 m_pDevice = NULL; 01726 } 01727 01728 friend class Device; 01729 PlaybackControl(Device* pDevice) : m_pDevice(NULL) 01730 { 01731 if (pDevice != NULL) 01732 { 01733 attach(pDevice); 01734 } 01735 } 01736 01737 Device* m_pDevice; 01738 }; 01739 01740 class CameraSettings 01741 { 01742 public: 01743 // setters 01744 Status setAutoExposureEnabled(bool enabled) 01745 { 01746 return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE); 01747 } 01748 Status setAutoWhiteBalanceEnabled(bool enabled) 01749 { 01750 return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE); 01751 } 01752 01753 bool getAutoExposureEnabled() const 01754 { 01755 OniBool enabled = FALSE; 01756 01757 Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled); 01758 return rc == STATUS_OK && enabled == TRUE; 01759 } 01760 bool getAutoWhiteBalanceEnabled() const 01761 { 01762 OniBool enabled = FALSE; 01763 01764 Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled); 01765 return rc == STATUS_OK && enabled == TRUE; 01766 } 01767 01768 bool isValid() const {return m_pStream != NULL;} 01769 private: 01770 template <class T> 01771 Status getProperty(int propertyId, T* value) const 01772 { 01773 if (!isValid()) return STATUS_NOT_SUPPORTED; 01774 01775 return m_pStream->getProperty<T>(propertyId, value); 01776 } 01777 template <class T> 01778 Status setProperty(int propertyId, const T& value) 01779 { 01780 if (!isValid()) return STATUS_NOT_SUPPORTED; 01781 01782 return m_pStream->setProperty<T>(propertyId, value); 01783 } 01784 01785 friend class VideoStream; 01786 CameraSettings(VideoStream* pStream) 01787 { 01788 m_pStream = pStream; 01789 } 01790 01791 VideoStream* m_pStream; 01792 }; 01793 01794 01807 class OpenNI 01808 { 01809 public: 01810 01826 class DeviceConnectedListener 01827 { 01828 public: 01829 DeviceConnectedListener() 01830 { 01831 m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback; 01832 m_deviceConnectedCallbacks.deviceDisconnected = NULL; 01833 m_deviceConnectedCallbacks.deviceStateChanged = NULL; 01834 m_deviceConnectedCallbacksHandle = NULL; 01835 } 01847 virtual void onDeviceConnected(const DeviceInfo*) = 0; 01848 private: 01849 static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01850 { 01851 DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie; 01852 pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo)); 01853 } 01854 01855 friend class OpenNI; 01856 OniDeviceCallbacks m_deviceConnectedCallbacks; 01857 OniCallbackHandle m_deviceConnectedCallbacksHandle; 01858 01859 }; 01876 class DeviceDisconnectedListener 01877 { 01878 public: 01879 DeviceDisconnectedListener() 01880 { 01881 m_deviceDisconnectedCallbacks.deviceConnected = NULL; 01882 m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback; 01883 m_deviceDisconnectedCallbacks.deviceStateChanged = NULL; 01884 m_deviceDisconnectedCallbacksHandle = NULL; 01885 } 01894 virtual void onDeviceDisconnected(const DeviceInfo*) = 0; 01895 private: 01896 static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01897 { 01898 DeviceDisconnectedListener* pListener = (DeviceDisconnectedListener*)pCookie; 01899 pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo)); 01900 } 01901 01902 friend class OpenNI; 01903 OniDeviceCallbacks m_deviceDisconnectedCallbacks; 01904 OniCallbackHandle m_deviceDisconnectedCallbacksHandle; 01905 }; 01919 class DeviceStateChangedListener 01920 { 01921 public: 01922 DeviceStateChangedListener() 01923 { 01924 m_deviceStateChangedCallbacks.deviceConnected = NULL; 01925 m_deviceStateChangedCallbacks.deviceDisconnected = NULL; 01926 m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback; 01927 m_deviceStateChangedCallbacksHandle = NULL; 01928 } 01935 virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0; 01936 private: 01937 static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie) 01938 { 01939 DeviceStateChangedListener* pListener = (DeviceStateChangedListener*)pCookie; 01940 pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state)); 01941 } 01942 01943 friend class OpenNI; 01944 OniDeviceCallbacks m_deviceStateChangedCallbacks; 01945 OniCallbackHandle m_deviceStateChangedCallbacksHandle; 01946 }; 01947 01953 static Status initialize() 01954 { 01955 return (Status)oniInitialize(ONI_API_VERSION); // provide version of API, to make sure proper struct sizes are used 01956 } 01957 01962 static void shutdown() 01963 { 01964 oniShutdown(); 01965 } 01966 01970 static Version getVersion() 01971 { 01972 OniVersion version = oniGetVersion(); 01973 union 01974 { 01975 OniVersion* pC; 01976 Version* pCpp; 01977 } a; 01978 a.pC = &version; 01979 return *a.pCpp; 01980 } 01981 01989 static const char* getExtendedError() 01990 { 01991 return oniGetExtendedError(); 01992 } 01993 01998 static void enumerateDevices(Array<DeviceInfo>* deviceInfoList) 01999 { 02000 OniDeviceInfo* m_pDeviceInfos; 02001 int m_deviceInfoCount; 02002 oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount); 02003 deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true); 02004 oniReleaseDeviceList(m_pDeviceInfos); 02005 } 02006 02015 static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER) 02016 { 02017 static const int ONI_MAX_STREAMS = 50; 02018 OniStreamHandle streams[ONI_MAX_STREAMS]; 02019 02020 if (streamCount > ONI_MAX_STREAMS) 02021 { 02022 printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS); 02023 return STATUS_BAD_PARAMETER; 02024 } 02025 02026 *pReadyStreamIndex = -1; 02027 for (int i = 0; i < streamCount; ++i) 02028 { 02029 if (pStreams[i] != NULL) 02030 { 02031 streams[i] = pStreams[i]->_getHandle(); 02032 } 02033 else 02034 { 02035 streams[i] = NULL; 02036 } 02037 } 02038 Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout); 02039 02040 return rc; 02041 } 02042 02050 static Status addDeviceConnectedListener(DeviceConnectedListener* pListener) 02051 { 02052 if (pListener->m_deviceConnectedCallbacksHandle != NULL) 02053 { 02054 return STATUS_ERROR; 02055 } 02056 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle); 02057 } 02065 static Status addDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02066 { 02067 if (pListener->m_deviceDisconnectedCallbacksHandle != NULL) 02068 { 02069 return STATUS_ERROR; 02070 } 02071 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle); 02072 } 02080 static Status addDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02081 { 02082 if (pListener->m_deviceStateChangedCallbacksHandle != NULL) 02083 { 02084 return STATUS_ERROR; 02085 } 02086 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle); 02087 } 02095 static void removeDeviceConnectedListener(DeviceConnectedListener* pListener) 02096 { 02097 oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle); 02098 pListener->m_deviceConnectedCallbacksHandle = NULL; 02099 } 02107 static void removeDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02108 { 02109 oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle); 02110 pListener->m_deviceDisconnectedCallbacksHandle = NULL; 02111 } 02119 static void removeDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02120 { 02121 oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle); 02122 pListener->m_deviceStateChangedCallbacksHandle = NULL; 02123 } 02124 private: 02125 OpenNI() 02126 { 02127 } 02128 }; 02129 02165 class CoordinateConverter 02166 { 02167 public: 02178 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ) 02179 { 02180 float depthX, depthY, depthZ; 02181 Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ); 02182 *pDepthX = (int)depthX; 02183 *pDepthY = (int)depthY; 02184 *pDepthZ = (DepthPixel)depthZ; 02185 return rc; 02186 } 02187 02198 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ) 02199 { 02200 return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ); 02201 } 02202 02213 static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02214 { 02215 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ); 02216 } 02217 02228 static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02229 { 02230 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ); 02231 } 02232 02244 static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY) 02245 { 02246 return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY); 02247 } 02248 }; 02249 02264 class Recorder 02265 { 02266 public: 02271 Recorder() : m_recorder(NULL) 02272 { 02273 } 02274 02278 ~Recorder() 02279 { 02280 destroy(); 02281 } 02282 02294 Status create(const char* fileName) 02295 { 02296 if (!isValid()) 02297 { 02298 return (Status)oniCreateRecorder(fileName, &m_recorder); 02299 } 02300 return STATUS_ERROR; 02301 } 02302 02309 bool isValid() const 02310 { 02311 return NULL != getHandle(); 02312 } 02313 02324 Status attach(VideoStream& stream, bool allowLossyCompression = false) 02325 { 02326 if (!isValid() || !stream.isValid()) 02327 { 02328 return STATUS_ERROR; 02329 } 02330 return (Status)oniRecorderAttachStream( 02331 m_recorder, 02332 stream._getHandle(), 02333 allowLossyCompression); 02334 } 02335 02342 Status start() 02343 { 02344 if (!isValid()) 02345 { 02346 return STATUS_ERROR; 02347 } 02348 return (Status)oniRecorderStart(m_recorder); 02349 } 02350 02354 void stop() 02355 { 02356 if (isValid()) 02357 { 02358 oniRecorderStop(m_recorder); 02359 } 02360 } 02361 02365 void destroy() 02366 { 02367 if (isValid()) 02368 { 02369 oniRecorderDestroy(&m_recorder); 02370 } 02371 } 02372 02373 private: 02374 Recorder(const Recorder&); 02375 Recorder& operator=(const Recorder&); 02376 02380 OniRecorderHandle getHandle() const 02381 { 02382 return m_recorder; 02383 } 02384 02385 02386 OniRecorderHandle m_recorder; 02387 }; 02388 02389 // Implemetation 02390 Status VideoStream::create(const Device& device, SensorType sensorType) 02391 { 02392 OniStreamHandle streamHandle; 02393 Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle); 02394 if (rc != STATUS_OK) 02395 { 02396 return rc; 02397 } 02398 02399 _setHandle(streamHandle); 02400 02401 if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE)) 02402 { 02403 m_pCameraSettings = new CameraSettings(this); 02404 } 02405 02406 return STATUS_OK; 02407 } 02408 02409 void VideoStream::destroy() 02410 { 02411 if (!isValid()) 02412 { 02413 return; 02414 } 02415 02416 if (m_pCameraSettings != NULL) 02417 { 02418 delete m_pCameraSettings; 02419 m_pCameraSettings = NULL; 02420 } 02421 02422 if (m_stream != NULL) 02423 { 02424 oniStreamDestroy(m_stream); 02425 m_stream = NULL; 02426 } 02427 } 02428 02429 Status Device::open(const char* uri) 02430 { 02431 OniDeviceHandle deviceHandle; 02432 Status rc = (Status)oniDeviceOpen(uri, &deviceHandle); 02433 if (rc != STATUS_OK) 02434 { 02435 return rc; 02436 } 02437 02438 _setHandle(deviceHandle); 02439 02440 if (isFile()) 02441 { 02442 m_pPlaybackControl = new PlaybackControl(this); 02443 } 02444 02445 return STATUS_OK; 02446 } 02447 02448 void Device::close() 02449 { 02450 if (m_pPlaybackControl != NULL) 02451 { 02452 delete m_pPlaybackControl; 02453 m_pPlaybackControl = NULL; 02454 } 02455 02456 if (m_device != NULL) 02457 { 02458 oniDeviceClose(m_device); 02459 m_device = NULL; 02460 } 02461 } 02462 02463 02464 } 02465 02466 #endif // _OPEN_NI_HPP_