OpenNI 2.0
OpenNI.h
Go to the documentation of this file.
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_