![]() |
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 00630 virtual void onNewFrame(VideoStream&) = 0; 00631 00632 private: 00633 friend class VideoStream; 00634 00635 static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie) 00636 { 00637 NewFrameListener* pListener = (NewFrameListener*)pCookie; 00638 VideoStream stream; 00639 stream._setHandle(streamHandle); 00640 pListener->onNewFrame(stream); 00641 stream._setHandle(NULL); 00642 } 00643 OniCallbackHandle m_callbackHandle; 00644 }; 00645 00650 VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL) 00651 {} 00652 00657 ~VideoStream() 00658 { 00659 destroy(); 00660 } 00661 00666 bool isValid() const 00667 { 00668 return m_stream != NULL; 00669 } 00670 00680 inline Status create(const Device& device, SensorType sensorType); 00681 00687 inline void destroy(); 00688 00697 const SensorInfo& getSensorInfo() const 00698 { 00699 return m_sensorInfo; 00700 } 00701 00705 Status start() 00706 { 00707 if (!isValid()) 00708 { 00709 return STATUS_ERROR; 00710 } 00711 00712 return (Status)oniStreamStart(m_stream); 00713 } 00714 00718 void stop() 00719 { 00720 if (!isValid()) 00721 { 00722 return; 00723 } 00724 00725 oniStreamStop(m_stream); 00726 } 00727 00738 Status readFrame(VideoFrameRef* pFrame) 00739 { 00740 if (!isValid()) 00741 { 00742 return STATUS_ERROR; 00743 } 00744 00745 OniFrame* pOniFrame; 00746 Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame); 00747 00748 pFrame->setReference(pOniFrame); 00749 return rc; 00750 } 00751 00759 Status addNewFrameListener(NewFrameListener* pListener) 00760 { 00761 if (!isValid()) 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 01145 class Device 01146 { 01147 public: 01152 Device() : m_pPlaybackControl(NULL), m_device(NULL) 01153 { 01154 clearSensors(); 01155 } 01156 01161 ~Device() 01162 { 01163 if (m_device != NULL) 01164 { 01165 close(); 01166 } 01167 } 01168 01198 inline Status open(const char* uri); 01199 01205 inline void close(); 01206 01216 const DeviceInfo& getDeviceInfo() const 01217 { 01218 return m_deviceInfo; 01219 } 01220 01228 bool hasSensor(SensorType sensorType) 01229 { 01230 int i; 01231 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01232 { 01233 if (m_aSensorInfo[i].getSensorType() == sensorType) 01234 { 01235 return true; 01236 } 01237 } 01238 01239 if (i == ONI_MAX_SENSORS) 01240 { 01241 return false; 01242 } 01243 01244 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01245 01246 if (pInfo == NULL) 01247 { 01248 return false; 01249 } 01250 01251 m_aSensorInfo[i]._setInternal(pInfo); 01252 01253 return true; 01254 } 01255 01263 const SensorInfo* getSensorInfo(SensorType sensorType) 01264 { 01265 int i; 01266 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01267 { 01268 if (m_aSensorInfo[i].getSensorType() == sensorType) 01269 { 01270 return &m_aSensorInfo[i]; 01271 } 01272 } 01273 01274 // not found. check to see we have additional space 01275 if (i == ONI_MAX_SENSORS) 01276 { 01277 return NULL; 01278 } 01279 01280 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01281 if (pInfo == NULL) 01282 { 01283 return NULL; 01284 } 01285 01286 m_aSensorInfo[i]._setInternal(pInfo); 01287 return &m_aSensorInfo[i]; 01288 } 01289 01294 OniDeviceHandle _getHandle() const 01295 { 01296 return m_device; 01297 } 01298 01303 PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;} 01304 01316 Status getProperty(int propertyId, void* data, int* dataSize) const 01317 { 01318 return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize); 01319 } 01320 01332 Status setProperty(int propertyId, const void* data, int dataSize) 01333 { 01334 return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize); 01335 } 01336 01344 bool isImageRegistrationModeSupported(ImageRegistrationMode mode) const 01345 { 01346 return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE); 01347 } 01348 01356 ImageRegistrationMode getImageRegistrationMode() const 01357 { 01358 ImageRegistrationMode mode; 01359 Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode); 01360 if (rc != STATUS_OK) 01361 { 01362 return IMAGE_REGISTRATION_OFF; 01363 } 01364 return mode; 01365 } 01366 01380 Status setImageRegistrationMode(ImageRegistrationMode mode) 01381 { 01382 return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode); 01383 } 01384 01389 bool isValid() const 01390 { 01391 return m_device != NULL; 01392 } 01393 01398 bool isFile() const 01399 { 01400 return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) && 01401 isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) && 01402 isCommandSupported(DEVICE_COMMAND_SEEK); 01403 } 01404 01413 Status setDepthColorSyncEnabled(bool isEnabled) 01414 { 01415 Status rc = STATUS_OK; 01416 01417 if (isEnabled) 01418 { 01419 rc = (Status)oniDeviceEnableDepthColorSync(m_device); 01420 } 01421 else 01422 { 01423 oniDeviceDisableDepthColorSync(m_device); 01424 } 01425 01426 return rc; 01427 } 01428 01439 template <class T> 01440 Status setProperty(int propertyId, const T& value) 01441 { 01442 return setProperty(propertyId, &value, sizeof(T)); 01443 } 01444 01454 template <class T> 01455 Status getProperty(int propertyId, T* value) const 01456 { 01457 int size = sizeof(T); 01458 return getProperty(propertyId, value, &size); 01459 } 01460 01466 bool isPropertySupported(int propertyId) const 01467 { 01468 return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE; 01469 } 01470 01480 Status invoke(int commandId, const void* data, int dataSize) 01481 { 01482 return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize); 01483 } 01484 01494 template <class T> 01495 Status invoke(int propertyId, const T& value) 01496 { 01497 return invoke(propertyId, &value, sizeof(T)); 01498 } 01499 01505 bool isCommandSupported(int commandId) const 01506 { 01507 return oniDeviceIsCommandSupported(m_device, commandId) == TRUE; 01508 } 01509 01510 private: 01511 Device(const Device&); 01512 Device& operator=(const Device&); 01513 01514 void clearSensors() 01515 { 01516 for (int i = 0; i < ONI_MAX_SENSORS; ++i) 01517 { 01518 m_aSensorInfo[i]._setInternal(NULL); 01519 } 01520 } 01521 01522 Status _setHandle(OniDeviceHandle deviceHandle) 01523 { 01524 if (m_device == NULL) 01525 { 01526 m_device = deviceHandle; 01527 01528 clearSensors(); 01529 01530 oniDeviceGetInfo(m_device, &m_deviceInfo); 01531 // Read deviceInfo 01532 return STATUS_OK; 01533 } 01534 01535 return STATUS_OUT_OF_FLOW; 01536 } 01537 01538 private: 01539 PlaybackControl* m_pPlaybackControl; 01540 01541 OniDeviceHandle m_device; 01542 DeviceInfo m_deviceInfo; 01543 SensorInfo m_aSensorInfo[ONI_MAX_SENSORS]; 01544 }; 01545 01559 class PlaybackControl 01560 { 01561 public: 01562 01568 ~PlaybackControl() 01569 { 01570 detach(); 01571 } 01572 01593 float getSpeed() const 01594 { 01595 if (!isValid()) 01596 { 01597 return 0.0f; 01598 } 01599 float speed; 01600 Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed); 01601 if (rc != STATUS_OK) 01602 { 01603 return 1.0f; 01604 } 01605 return speed; 01606 } 01614 Status setSpeed(float speed) 01615 { 01616 if (!isValid()) 01617 { 01618 return STATUS_NO_DEVICE; 01619 } 01620 return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed); 01621 } 01622 01628 bool getRepeatEnabled() const 01629 { 01630 if (!isValid()) 01631 { 01632 return false; 01633 } 01634 01635 OniBool repeat; 01636 Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat); 01637 if (rc != STATUS_OK) 01638 { 01639 return false; 01640 } 01641 01642 return repeat == TRUE; 01643 } 01644 01653 Status setRepeatEnabled(bool repeat) 01654 { 01655 if (!isValid()) 01656 { 01657 return STATUS_NO_DEVICE; 01658 } 01659 01660 return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE); 01661 } 01662 01673 Status seek(const VideoStream& stream, int frameIndex) 01674 { 01675 if (!isValid()) 01676 { 01677 return STATUS_NO_DEVICE; 01678 } 01679 OniSeek seek; 01680 seek.frameIndex = frameIndex; 01681 seek.stream = stream._getHandle(); 01682 return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek); 01683 } 01684 01693 int getNumberOfFrames(const VideoStream& stream) const 01694 { 01695 int numOfFrames = -1; 01696 Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames); 01697 if (rc != STATUS_OK) 01698 { 01699 return 0; 01700 } 01701 return numOfFrames; 01702 } 01703 01704 bool isValid() const 01705 { 01706 return m_pDevice != NULL; 01707 } 01708 private: 01709 Status attach(Device* device) 01710 { 01711 if (!device->isValid() || !device->isFile()) 01712 { 01713 return STATUS_ERROR; 01714 } 01715 01716 detach(); 01717 m_pDevice = device; 01718 01719 return STATUS_OK; 01720 } 01721 void detach() 01722 { 01723 m_pDevice = NULL; 01724 } 01725 01726 friend class Device; 01727 PlaybackControl(Device* pDevice) : m_pDevice(NULL) 01728 { 01729 if (pDevice != NULL) 01730 { 01731 attach(pDevice); 01732 } 01733 } 01734 01735 Device* m_pDevice; 01736 }; 01737 01738 class CameraSettings 01739 { 01740 public: 01741 // setters 01742 Status setAutoExposureEnabled(bool enabled) 01743 { 01744 return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE); 01745 } 01746 Status setAutoWhiteBalanceEnabled(bool enabled) 01747 { 01748 return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE); 01749 } 01750 01751 bool getAutoExposureEnabled() const 01752 { 01753 OniBool enabled = FALSE; 01754 01755 Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled); 01756 return rc == STATUS_OK && enabled == TRUE; 01757 } 01758 bool getAutoWhiteBalanceEnabled() const 01759 { 01760 OniBool enabled = FALSE; 01761 01762 Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled); 01763 return rc == STATUS_OK && enabled == TRUE; 01764 } 01765 01766 bool isValid() const {return m_pStream != NULL;} 01767 private: 01768 template <class T> 01769 Status getProperty(int propertyId, T* value) const 01770 { 01771 if (!isValid()) return STATUS_NOT_SUPPORTED; 01772 01773 return m_pStream->getProperty<T>(propertyId, value); 01774 } 01775 template <class T> 01776 Status setProperty(int propertyId, const T& value) 01777 { 01778 if (!isValid()) return STATUS_NOT_SUPPORTED; 01779 01780 return m_pStream->setProperty<T>(propertyId, value); 01781 } 01782 01783 friend class VideoStream; 01784 CameraSettings(VideoStream* pStream) 01785 { 01786 m_pStream = pStream; 01787 } 01788 01789 VideoStream* m_pStream; 01790 }; 01791 01792 01805 class OpenNI 01806 { 01807 public: 01808 01824 class DeviceConnectedListener 01825 { 01826 public: 01827 DeviceConnectedListener() 01828 { 01829 m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback; 01830 m_deviceConnectedCallbacks.deviceDisconnected = NULL; 01831 m_deviceConnectedCallbacks.deviceStateChanged = NULL; 01832 m_deviceConnectedCallbacksHandle = NULL; 01833 } 01845 virtual void onDeviceConnected(const DeviceInfo*) = 0; 01846 private: 01847 static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01848 { 01849 DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie; 01850 pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo)); 01851 } 01852 01853 friend class OpenNI; 01854 OniDeviceCallbacks m_deviceConnectedCallbacks; 01855 OniCallbackHandle m_deviceConnectedCallbacksHandle; 01856 01857 }; 01874 class DeviceDisconnectedListener 01875 { 01876 public: 01877 DeviceDisconnectedListener() 01878 { 01879 m_deviceDisconnectedCallbacks.deviceConnected = NULL; 01880 m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback; 01881 m_deviceDisconnectedCallbacks.deviceStateChanged = NULL; 01882 m_deviceDisconnectedCallbacksHandle = NULL; 01883 } 01892 virtual void onDeviceDisconnected(const DeviceInfo*) = 0; 01893 private: 01894 static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01895 { 01896 DeviceDisconnectedListener* pListener = (DeviceDisconnectedListener*)pCookie; 01897 pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo)); 01898 } 01899 01900 friend class OpenNI; 01901 OniDeviceCallbacks m_deviceDisconnectedCallbacks; 01902 OniCallbackHandle m_deviceDisconnectedCallbacksHandle; 01903 }; 01917 class DeviceStateChangedListener 01918 { 01919 public: 01920 DeviceStateChangedListener() 01921 { 01922 m_deviceStateChangedCallbacks.deviceConnected = NULL; 01923 m_deviceStateChangedCallbacks.deviceDisconnected = NULL; 01924 m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback; 01925 m_deviceStateChangedCallbacksHandle = NULL; 01926 } 01933 virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0; 01934 private: 01935 static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie) 01936 { 01937 DeviceStateChangedListener* pListener = (DeviceStateChangedListener*)pCookie; 01938 pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state)); 01939 } 01940 01941 friend class OpenNI; 01942 OniDeviceCallbacks m_deviceStateChangedCallbacks; 01943 OniCallbackHandle m_deviceStateChangedCallbacksHandle; 01944 }; 01945 01951 static Status initialize() 01952 { 01953 return (Status)oniInitialize(ONI_API_VERSION); // provide version of API, to make sure proper struct sizes are used 01954 } 01955 01960 static void shutdown() 01961 { 01962 oniShutdown(); 01963 } 01964 01968 static Version getVersion() 01969 { 01970 OniVersion version = oniGetVersion(); 01971 union 01972 { 01973 OniVersion* pC; 01974 Version* pCpp; 01975 } a; 01976 a.pC = &version; 01977 return *a.pCpp; 01978 } 01979 01987 static const char* getExtendedError() 01988 { 01989 return oniGetExtendedError(); 01990 } 01991 01996 static void enumerateDevices(Array<DeviceInfo>* deviceInfoList) 01997 { 01998 OniDeviceInfo* m_pDeviceInfos; 01999 int m_deviceInfoCount; 02000 oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount); 02001 deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true); 02002 oniReleaseDeviceList(m_pDeviceInfos); 02003 } 02004 02013 static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER) 02014 { 02015 static const int ONI_MAX_STREAMS = 50; 02016 OniStreamHandle streams[ONI_MAX_STREAMS]; 02017 02018 if (streamCount > ONI_MAX_STREAMS) 02019 { 02020 printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS); 02021 return STATUS_BAD_PARAMETER; 02022 } 02023 02024 *pReadyStreamIndex = -1; 02025 for (int i = 0; i < streamCount; ++i) 02026 { 02027 if (pStreams[i] != NULL) 02028 { 02029 streams[i] = pStreams[i]->_getHandle(); 02030 } 02031 else 02032 { 02033 streams[i] = NULL; 02034 } 02035 } 02036 Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout); 02037 02038 return rc; 02039 } 02040 02048 static Status addDeviceConnectedListener(DeviceConnectedListener* pListener) 02049 { 02050 if (pListener->m_deviceConnectedCallbacksHandle != NULL) 02051 { 02052 return STATUS_ERROR; 02053 } 02054 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle); 02055 } 02063 static Status addDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02064 { 02065 if (pListener->m_deviceDisconnectedCallbacksHandle != NULL) 02066 { 02067 return STATUS_ERROR; 02068 } 02069 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle); 02070 } 02078 static Status addDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02079 { 02080 if (pListener->m_deviceStateChangedCallbacksHandle != NULL) 02081 { 02082 return STATUS_ERROR; 02083 } 02084 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle); 02085 } 02093 static void removeDeviceConnectedListener(DeviceConnectedListener* pListener) 02094 { 02095 oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle); 02096 pListener->m_deviceConnectedCallbacksHandle = NULL; 02097 } 02105 static void removeDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02106 { 02107 oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle); 02108 pListener->m_deviceDisconnectedCallbacksHandle = NULL; 02109 } 02117 static void removeDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02118 { 02119 oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle); 02120 pListener->m_deviceStateChangedCallbacksHandle = NULL; 02121 } 02122 private: 02123 OpenNI() 02124 { 02125 } 02126 }; 02127 02163 class CoordinateConverter 02164 { 02165 public: 02176 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ) 02177 { 02178 float depthX, depthY, depthZ; 02179 Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ); 02180 *pDepthX = (int)depthX; 02181 *pDepthY = (int)depthY; 02182 *pDepthZ = (DepthPixel)depthZ; 02183 return rc; 02184 } 02185 02196 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ) 02197 { 02198 return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ); 02199 } 02200 02211 static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02212 { 02213 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ); 02214 } 02215 02226 static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02227 { 02228 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ); 02229 } 02230 02242 static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY) 02243 { 02244 return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY); 02245 } 02246 }; 02247 02262 class Recorder 02263 { 02264 public: 02269 Recorder() : m_recorder(NULL) 02270 { 02271 } 02272 02276 ~Recorder() 02277 { 02278 destroy(); 02279 } 02280 02292 Status create(const char* fileName) 02293 { 02294 if (!isValid()) 02295 { 02296 return (Status)oniCreateRecorder(fileName, &m_recorder); 02297 } 02298 return STATUS_ERROR; 02299 } 02300 02307 bool isValid() const 02308 { 02309 return NULL != getHandle(); 02310 } 02311 02322 Status attach(VideoStream& stream, bool allowLossyCompression = false) 02323 { 02324 if (!isValid() || !stream.isValid()) 02325 { 02326 return STATUS_ERROR; 02327 } 02328 return (Status)oniRecorderAttachStream( 02329 m_recorder, 02330 stream._getHandle(), 02331 allowLossyCompression); 02332 } 02333 02340 Status start() 02341 { 02342 if (!isValid()) 02343 { 02344 return STATUS_ERROR; 02345 } 02346 return (Status)oniRecorderStart(m_recorder); 02347 } 02348 02352 void stop() 02353 { 02354 if (isValid()) 02355 { 02356 oniRecorderStop(m_recorder); 02357 } 02358 } 02359 02363 void destroy() 02364 { 02365 if (isValid()) 02366 { 02367 oniRecorderDestroy(&m_recorder); 02368 } 02369 } 02370 02371 private: 02372 Recorder(const Recorder&); 02373 Recorder& operator=(const Recorder&); 02374 02378 OniRecorderHandle getHandle() const 02379 { 02380 return m_recorder; 02381 } 02382 02383 02384 OniRecorderHandle m_recorder; 02385 }; 02386 02387 // Implemetation 02388 Status VideoStream::create(const Device& device, SensorType sensorType) 02389 { 02390 OniStreamHandle streamHandle; 02391 Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle); 02392 if (rc != STATUS_OK) 02393 { 02394 return rc; 02395 } 02396 02397 _setHandle(streamHandle); 02398 02399 if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE)) 02400 { 02401 m_pCameraSettings = new CameraSettings(this); 02402 } 02403 02404 return STATUS_OK; 02405 } 02406 02407 void VideoStream::destroy() 02408 { 02409 if (!isValid()) 02410 { 02411 return; 02412 } 02413 02414 if (m_pCameraSettings != NULL) 02415 { 02416 delete m_pCameraSettings; 02417 m_pCameraSettings = NULL; 02418 } 02419 02420 if (m_stream != NULL) 02421 { 02422 oniStreamDestroy(m_stream); 02423 m_stream = NULL; 02424 } 02425 } 02426 02427 Status Device::open(const char* uri) 02428 { 02429 OniDeviceHandle deviceHandle; 02430 Status rc = (Status)oniDeviceOpen(uri, &deviceHandle); 02431 if (rc != STATUS_OK) 02432 { 02433 return rc; 02434 } 02435 02436 _setHandle(deviceHandle); 02437 02438 if (isFile()) 02439 { 02440 m_pPlaybackControl = new PlaybackControl(this); 02441 } 02442 02443 return STATUS_OK; 02444 } 02445 02446 void Device::close() 02447 { 02448 if (m_pPlaybackControl != NULL) 02449 { 02450 delete m_pPlaybackControl; 02451 m_pPlaybackControl = NULL; 02452 } 02453 02454 if (m_device != NULL) 02455 { 02456 oniDeviceClose(m_device); 02457 m_device = NULL; 02458 } 02459 } 02460 02461 02462 } 02463 02464 #endif // _OPEN_NI_HPP_