OpenNI 2.0
OpenNI.h
Go to the documentation of this file.
1 /*****************************************************************************
2 * *
3 * OpenNI 2.x Alpha *
4 * Copyright (C) 2012 PrimeSense Ltd. *
5 * *
6 * This file is part of OpenNI. *
7 * *
8 * Licensed under the Apache License, Version 2.0 (the "License"); *
9 * you may not use this file except in compliance with the License. *
10 * You may obtain a copy of the License at *
11 * *
12 * http://www.apache.org/licenses/LICENSE-2.0 *
13 * *
14 * Unless required by applicable law or agreed to in writing, software *
15 * distributed under the License is distributed on an "AS IS" BASIS, *
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
17 * See the License for the specific language governing permissions and *
18 * limitations under the License. *
19 * *
20 *****************************************************************************/
21 #ifndef _OPENNI_H_
22 #define _OPENNI_H_
23 
24 #include "OniPlatform.h"
25 #include "OniProperties.h"
26 #include "OniEnums.h"
27 
28 #include "OniCAPI.h"
29 #include "OniCProperties.h"
30 
34 namespace openni
35 {
36 
38 typedef uint16_t DepthPixel;
40 typedef uint16_t Grayscale16Pixel;
41 
42 // structs
43 _ONI_DECLARE_VERSION(Version);
44 _ONI_DECLARE_RGB888_PIXEL(RGB888Pixel);
45 _ONI_DECLARE_YUV422_PIXEL(YUV422DoublePixel);
46 
48 #if ONI_PLATFORM != ONI_PLATFORM_WIN32
49 #pragma GCC diagnostic ignored "-Wunused-variable"
50 #pragma GCC diagnostic push
51 #endif
52 static const char* ANY_DEVICE = NULL;
53 #if ONI_PLATFORM != ONI_PLATFORM_WIN32
54 #pragma GCC diagnostic pop
55 #endif
56 
61 template<class T>
62 class Array
63 {
64 public:
68  Array() : m_data(NULL), m_count(0), m_owner(false) {}
69 
77  Array(const T* data, int count) : m_owner(false) { _setData(data, count); }
78 
83  {
84  clear();
85  }
86 
91  int getSize() const { return m_count; }
92 
96  const T& operator[](int index) const {return m_data[index];}
97 
108  void _setData(const T* data, int count, bool isOwner = false)
109  {
110  clear();
111  m_count = count;
112  m_owner = isOwner;
113  if (!isOwner)
114  {
115  m_data = data;
116  }
117  else
118  {
119  m_data = new T[count];
120  memcpy((void*)m_data, data, count*sizeof(T));
121  }
122  }
123 
124 private:
125  Array(const Array<T>&);
126  Array<T>& operator=(const Array<T>&);
127 
128  void clear()
129  {
130  if (m_owner && m_data != NULL)
131  delete []m_data;
132  m_owner = false;
133  m_data = NULL;
134  m_count = 0;
135  }
136 
137  const T* m_data;
138  int m_count;
139  bool m_owner;
140 };
141 
142 // Forward declaration of all
143 class SensorInfo;
144 class VideoStream;
145 class VideoFrameRef;
146 class Device;
147 class OpenNI;
148 class CameraSettings;
149 class PlaybackControl;
150 
165 class VideoMode : private OniVideoMode
166 {
167 public:
174  {}
175 
181  VideoMode(const VideoMode& other)
182  {
183  *this = other;
184  }
185 
193  {
195  setResolution(other.getResolutionX(), other.getResolutionY());
196  setFps(other.getFps());
197 
198  return *this;
199  }
200 
205  PixelFormat getPixelFormat() const { return (PixelFormat)pixelFormat; }
206 
211  int getResolutionX() const { return resolutionX; }
212 
217  int getResolutionY() const {return resolutionY;}
218 
223  int getFps() const { return fps; }
224 
231  void setPixelFormat(PixelFormat format) { this->pixelFormat = (OniPixelFormat)format; }
232 
240  void setResolution(int resolutionX, int resolutionY)
241  {
242  this->resolutionX = resolutionX;
243  this->resolutionY = resolutionY;
244  }
245 
252  void setFps(int fps) { this->fps = fps; }
253 
254  friend class SensorInfo;
255  friend class VideoStream;
256  friend class VideoFrameRef;
257 };
258 
277 {
278 public:
283  SensorType getSensorType() const { return (SensorType)m_pInfo->sensorType; }
284 
292  const Array<VideoMode>& getSupportedVideoModes() const { return m_videoModes; }
293 
294 private:
295  SensorInfo(const SensorInfo&);
296  SensorInfo& operator=(const SensorInfo&);
297 
298  SensorInfo() : m_pInfo(NULL), m_videoModes(NULL, 0) {}
299 
300  SensorInfo(const OniSensorInfo* pInfo) : m_pInfo(NULL), m_videoModes(NULL, 0)
301  {
302  _setInternal(pInfo);
303  }
304 
305  void _setInternal(const OniSensorInfo* pInfo)
306  {
307  m_pInfo = pInfo;
308  if (pInfo == NULL)
309  {
310  m_videoModes._setData(NULL, 0);
311  }
312  else
313  {
314  m_videoModes._setData(static_cast<VideoMode*>(pInfo->pSupportedVideoModes), pInfo->numSupportedVideoModes);
315  }
316  }
317 
318  const OniSensorInfo* m_pInfo;
319  Array<VideoMode> m_videoModes;
320 
321  friend class VideoStream;
322  friend class Device;
323 };
324 
334 class DeviceInfo : private OniDeviceInfo
335 {
336 public:
341  const char* getUri() const { return uri; }
343  const char* getVendor() const { return vendor; }
345  const char* getName() const { return name; }
347  uint16_t getUsbVendorId() const { return usbVendorId; }
349  uint16_t getUsbProductId() const { return usbProductId; }
350 
351  friend class Device;
352  friend class OpenNI;
353 };
354 
369 {
370 public:
376  {
377  m_pFrame = NULL;
378  }
379 
384  {
385  release();
386  }
387 
393  VideoFrameRef(const VideoFrameRef& other) : m_pFrame(NULL)
394  {
395  _setFrame(other.m_pFrame);
396  }
397 
404  {
405  _setFrame(other.m_pFrame);
406  return *this;
407  }
408 
414  inline int getDataSize() const
415  {
416  return m_pFrame->dataSize;
417  }
418 
424  inline const void* getData() const
425  {
426  return m_pFrame->data;
427  }
428 
435  inline SensorType getSensorType() const
436  {
437  return (SensorType)m_pFrame->sensorType;
438  }
439 
447  inline const VideoMode& getVideoMode() const
448  {
449  return static_cast<const VideoMode&>(m_pFrame->videoMode);
450  }
451 
459  inline uint64_t getTimestamp() const
460  {
461  return m_pFrame->timestamp;
462  }
463 
474  inline int getFrameIndex() const
475  {
476  return m_pFrame->frameIndex;
477  }
478 
485  inline int getWidth() const
486  {
487  return m_pFrame->width;
488  }
489 
495  inline int getHeight() const
496  {
497  return m_pFrame->height;
498  }
499 
504  inline bool getCroppingEnabled() const
505  {
506  return m_pFrame->croppingEnabled == TRUE;
507  }
508 
513  inline int getCropOriginX() const
514  {
515  return m_pFrame->cropOriginX;
516  }
517 
522  inline int getCropOriginY() const
523  {
524  return m_pFrame->cropOriginY;
525  }
526 
532  inline int getStrideInBytes() const
533  {
534  return m_pFrame->stride;
535  }
536 
540  inline bool isValid() const
541  {
542  return m_pFrame != NULL;
543  }
544 
549  void release()
550  {
551  if (m_pFrame != NULL)
552  {
553  oniFrameRelease(m_pFrame);
554  m_pFrame = NULL;
555  }
556  }
557 
559  void _setFrame(OniFrame* pFrame)
560  {
561  setReference(pFrame);
562  if (pFrame != NULL)
563  {
564  oniFrameAddRef(pFrame);
565  }
566  }
567 
569  OniFrame* _getFrame()
570  {
571  return m_pFrame;
572  }
573 
574 private:
575  friend class VideoStream;
576  inline void setReference(OniFrame* pFrame)
577  {
578  // Initial - don't addref. This is the reference from OpenNI
579  release();
580  m_pFrame = pFrame;
581  }
582 
583  OniFrame* m_pFrame; // const!!?
584 };
585 
608 {
609 public:
618  {
619  public:
623  NewFrameListener() : m_callbackHandle(NULL)
624  {
625  }
626 
630  virtual void onNewFrame(VideoStream&) = 0;
631 
632  private:
633  friend class VideoStream;
634 
635  static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie)
636  {
637  NewFrameListener* pListener = (NewFrameListener*)pCookie;
638  VideoStream stream;
639  stream._setHandle(streamHandle);
640  pListener->onNewFrame(stream);
641  stream._setHandle(NULL);
642  }
643  OniCallbackHandle m_callbackHandle;
644  };
645 
650  VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL)
651  {}
652 
658  {
659  destroy();
660  }
661 
666  bool isValid() const
667  {
668  return m_stream != NULL;
669  }
670 
680  inline Status create(const Device& device, SensorType sensorType);
681 
687  inline void destroy();
688 
697  const SensorInfo& getSensorInfo() const
698  {
699  return m_sensorInfo;
700  }
701 
706  {
707  if (!isValid())
708  {
709  return STATUS_ERROR;
710  }
711 
712  return (Status)oniStreamStart(m_stream);
713  }
714 
718  void stop()
719  {
720  if (!isValid())
721  {
722  return;
723  }
724 
725  oniStreamStop(m_stream);
726  }
727 
739  {
740  if (!isValid())
741  {
742  return STATUS_ERROR;
743  }
744 
745  OniFrame* pOniFrame;
746  Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame);
747 
748  pFrame->setReference(pOniFrame);
749  return rc;
750  }
751 
760  {
761  if (!isValid())
762  {
763  return STATUS_ERROR;
764  }
765 
766  return (Status)oniStreamRegisterNewFrameCallback(m_stream, pListener->callback, pListener, &pListener->m_callbackHandle);
767  }
768 
774  {
775  if (!isValid())
776  {
777  return;
778  }
779 
780  oniStreamUnregisterNewFrameCallback(m_stream, pListener->m_callbackHandle);
781  pListener->m_callbackHandle = NULL;
782  }
783 
788  OniStreamHandle _getHandle() const
789  {
790  return m_stream;
791  }
792 
797  CameraSettings* getCameraSettings() {return m_pCameraSettings;}
798 
809  Status getProperty(int propertyId, void* data, int* dataSize) const
810  {
811  if (!isValid())
812  {
813  return STATUS_ERROR;
814  }
815 
816  return (Status)oniStreamGetProperty(m_stream, propertyId, data, dataSize);
817  }
818 
829  Status setProperty(int propertyId, const void* data, int dataSize)
830  {
831  if (!isValid())
832  {
833  return STATUS_ERROR;
834  }
835 
836  return (Status)oniStreamSetProperty(m_stream, propertyId, data, dataSize);
837  }
838 
846  {
847  VideoMode videoMode;
848  getProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<OniVideoMode*>(&videoMode));
849  return videoMode;
850  }
851 
860  Status setVideoMode(const VideoMode& videoMode)
861  {
862  return setProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<const OniVideoMode&>(videoMode));
863  }
864 
870  int getMaxPixelValue() const
871  {
872  int maxValue;
873  Status rc = getProperty<int>(STREAM_PROPERTY_MAX_VALUE, &maxValue);
874  if (rc != STATUS_OK)
875  {
876  return 0;
877  }
878  return maxValue;
879  }
880 
886  int getMinPixelValue() const
887  {
888  int minValue;
889  Status rc = getProperty<int>(STREAM_PROPERTY_MIN_VALUE, &minValue);
890  if (rc != STATUS_OK)
891  {
892  return 0;
893  }
894  return minValue;
895  }
896 
901  bool isCroppingSupported() const
902  {
903  return isPropertySupported(STREAM_PROPERTY_CROPPING);
904  }
905 
914  bool getCropping(int* pOriginX, int* pOriginY, int* pWidth, int* pHeight) const
915  {
916  OniCropping cropping;
917  bool enabled = false;
918 
919  Status rc = getProperty<OniCropping>(STREAM_PROPERTY_CROPPING, &cropping);
920 
921  if (rc == STATUS_OK)
922  {
923  *pOriginX = cropping.originX;
924  *pOriginY = cropping.originY;
925  *pWidth = cropping.width;
926  *pHeight = cropping.height;
927  enabled = (cropping.enabled == TRUE);
928  }
929 
930  return enabled;
931  }
932 
942  Status setCropping(int originX, int originY, int width, int height)
943  {
944  OniCropping cropping;
945  cropping.enabled = true;
946  cropping.originX = originX;
947  cropping.originY = originY;
948  cropping.width = width;
949  cropping.height = height;
950  return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping);
951  }
952 
958  {
959  OniCropping cropping;
960  cropping.enabled = false;
961  return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping);
962  }
963 
968  bool getMirroringEnabled() const
969  {
970  OniBool enabled;
971  Status rc = getProperty<OniBool>(STREAM_PROPERTY_MIRRORING, &enabled);
972  if (rc != STATUS_OK)
973  {
974  return false;
975  }
976  return enabled == TRUE;
977  }
978 
984  Status setMirroringEnabled(bool isEnabled)
985  {
986  return setProperty<OniBool>(STREAM_PROPERTY_MIRRORING, isEnabled ? TRUE : FALSE);
987  }
988 
994  {
995  float horizontal = 0;
996  getProperty<float>(STREAM_PROPERTY_HORIZONTAL_FOV, &horizontal);
997  return horizontal;
998  }
999 
1005  {
1006  float vertical = 0;
1007  getProperty<float>(STREAM_PROPERTY_VERTICAL_FOV, &vertical);
1008  return vertical;
1009  }
1010 
1020  template <class T>
1021  Status setProperty(int propertyId, const T& value)
1022  {
1023  return setProperty(propertyId, &value, sizeof(T));
1024  }
1025 
1035  template <class T>
1036  Status getProperty(int propertyId, T* value) const
1037  {
1038  int size = sizeof(T);
1039  return getProperty(propertyId, value, &size);
1040  }
1041 
1047  bool isPropertySupported(int propertyId) const
1048  {
1049  if (!isValid())
1050  {
1051  return false;
1052  }
1053 
1054  return oniStreamIsPropertySupported(m_stream, propertyId) == TRUE;
1055  }
1056 
1066  Status invoke(int commandId, void* data, int dataSize)
1067  {
1068  if (!isValid())
1069  {
1070  return STATUS_ERROR;
1071  }
1072 
1073  return (Status)oniStreamInvoke(m_stream, commandId, data, dataSize);
1074  }
1075 
1085  template <class T>
1086  Status invoke(int commandId, const T& value)
1087  {
1088  return invoke(commandId, &value, sizeof(T));
1089  }
1090 
1096  bool isCommandSupported(int commandId) const
1097  {
1098  if (!isValid())
1099  {
1100  return false;
1101  }
1102 
1103  return (Status)oniStreamIsCommandSupported(m_stream, commandId) == TRUE;
1104  }
1105 
1106 private:
1107  friend class Device;
1108 
1109  void _setHandle(OniStreamHandle stream)
1110  {
1111  m_sensorInfo._setInternal(NULL);
1112  m_stream = stream;
1113 
1114  if (stream != NULL)
1115  {
1116  m_sensorInfo._setInternal(oniStreamGetSensorInfo(m_stream));
1117  }
1118  }
1119 
1120 private:
1121  VideoStream(const VideoStream& other);
1122  VideoStream& operator=(const VideoStream& other);
1123 
1124  OniStreamHandle m_stream;
1125  SensorInfo m_sensorInfo;
1126  CameraSettings* m_pCameraSettings;
1127 };
1128 
1145 class Device
1146 {
1147 public:
1152  Device() : m_pPlaybackControl(NULL), m_device(NULL)
1153  {
1154  clearSensors();
1155  }
1156 
1162  {
1163  if (m_device != NULL)
1164  {
1165  close();
1166  }
1167  }
1168 
1198  inline Status open(const char* uri);
1199 
1205  inline void close();
1206 
1216  const DeviceInfo& getDeviceInfo() const
1217  {
1218  return m_deviceInfo;
1219  }
1220 
1228  bool hasSensor(SensorType sensorType)
1229  {
1230  int i;
1231  for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i)
1232  {
1233  if (m_aSensorInfo[i].getSensorType() == sensorType)
1234  {
1235  return true;
1236  }
1237  }
1238 
1239  if (i == ONI_MAX_SENSORS)
1240  {
1241  return false;
1242  }
1243 
1244  const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType);
1245 
1246  if (pInfo == NULL)
1247  {
1248  return false;
1249  }
1250 
1251  m_aSensorInfo[i]._setInternal(pInfo);
1252 
1253  return true;
1254  }
1255 
1264  {
1265  int i;
1266  for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i)
1267  {
1268  if (m_aSensorInfo[i].getSensorType() == sensorType)
1269  {
1270  return &m_aSensorInfo[i];
1271  }
1272  }
1273 
1274  // not found. check to see we have additional space
1275  if (i == ONI_MAX_SENSORS)
1276  {
1277  return NULL;
1278  }
1279 
1280  const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType);
1281  if (pInfo == NULL)
1282  {
1283  return NULL;
1284  }
1285 
1286  m_aSensorInfo[i]._setInternal(pInfo);
1287  return &m_aSensorInfo[i];
1288  }
1289 
1294  OniDeviceHandle _getHandle() const
1295  {
1296  return m_device;
1297  }
1298 
1303  PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;}
1304 
1316  Status getProperty(int propertyId, void* data, int* dataSize) const
1317  {
1318  return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize);
1319  }
1320 
1332  Status setProperty(int propertyId, const void* data, int dataSize)
1333  {
1334  return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize);
1335  }
1336 
1345  {
1346  return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE);
1347  }
1348 
1357  {
1358  ImageRegistrationMode mode;
1359  Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode);
1360  if (rc != STATUS_OK)
1361  {
1362  return IMAGE_REGISTRATION_OFF;
1363  }
1364  return mode;
1365  }
1366 
1381  {
1382  return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode);
1383  }
1384 
1389  bool isValid() const
1390  {
1391  return m_device != NULL;
1392  }
1393 
1398  bool isFile() const
1399  {
1400  return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) &&
1401  isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) &&
1402  isCommandSupported(DEVICE_COMMAND_SEEK);
1403  }
1404 
1414  {
1415  Status rc = STATUS_OK;
1416 
1417  if (isEnabled)
1418  {
1419  rc = (Status)oniDeviceEnableDepthColorSync(m_device);
1420  }
1421  else
1422  {
1423  oniDeviceDisableDepthColorSync(m_device);
1424  }
1425 
1426  return rc;
1427  }
1428 
1439  template <class T>
1440  Status setProperty(int propertyId, const T& value)
1441  {
1442  return setProperty(propertyId, &value, sizeof(T));
1443  }
1444 
1454  template <class T>
1455  Status getProperty(int propertyId, T* value) const
1456  {
1457  int size = sizeof(T);
1458  return getProperty(propertyId, value, &size);
1459  }
1460 
1466  bool isPropertySupported(int propertyId) const
1467  {
1468  return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE;
1469  }
1470 
1480  Status invoke(int commandId, const void* data, int dataSize)
1481  {
1482  return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize);
1483  }
1484 
1494  template <class T>
1495  Status invoke(int propertyId, const T& value)
1496  {
1497  return invoke(propertyId, &value, sizeof(T));
1498  }
1499 
1505  bool isCommandSupported(int commandId) const
1506  {
1507  return oniDeviceIsCommandSupported(m_device, commandId) == TRUE;
1508  }
1509 
1510 private:
1511  Device(const Device&);
1512  Device& operator=(const Device&);
1513 
1514  void clearSensors()
1515  {
1516  for (int i = 0; i < ONI_MAX_SENSORS; ++i)
1517  {
1518  m_aSensorInfo[i]._setInternal(NULL);
1519  }
1520  }
1521 
1522  Status _setHandle(OniDeviceHandle deviceHandle)
1523  {
1524  if (m_device == NULL)
1525  {
1526  m_device = deviceHandle;
1527 
1528  clearSensors();
1529 
1530  oniDeviceGetInfo(m_device, &m_deviceInfo);
1531  // Read deviceInfo
1532  return STATUS_OK;
1533  }
1534 
1535  return STATUS_OUT_OF_FLOW;
1536  }
1537 
1538 private:
1539  PlaybackControl* m_pPlaybackControl;
1540 
1541  OniDeviceHandle m_device;
1542  DeviceInfo m_deviceInfo;
1543  SensorInfo m_aSensorInfo[ONI_MAX_SENSORS];
1544 };
1545 
1560 {
1561 public:
1562 
1569  {
1570  detach();
1571  }
1572 
1593  float getSpeed() const
1594  {
1595  if (!isValid())
1596  {
1597  return 0.0f;
1598  }
1599  float speed;
1600  Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed);
1601  if (rc != STATUS_OK)
1602  {
1603  return 1.0f;
1604  }
1605  return speed;
1606  }
1614  Status setSpeed(float speed)
1615  {
1616  if (!isValid())
1617  {
1618  return STATUS_NO_DEVICE;
1619  }
1620  return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed);
1621  }
1622 
1628  bool getRepeatEnabled() const
1629  {
1630  if (!isValid())
1631  {
1632  return false;
1633  }
1634 
1635  OniBool repeat;
1636  Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat);
1637  if (rc != STATUS_OK)
1638  {
1639  return false;
1640  }
1641 
1642  return repeat == TRUE;
1643  }
1644 
1654  {
1655  if (!isValid())
1656  {
1657  return STATUS_NO_DEVICE;
1658  }
1659 
1660  return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE);
1661  }
1662 
1673  Status seek(const VideoStream& stream, int frameIndex)
1674  {
1675  if (!isValid())
1676  {
1677  return STATUS_NO_DEVICE;
1678  }
1679  OniSeek seek;
1680  seek.frameIndex = frameIndex;
1681  seek.stream = stream._getHandle();
1682  return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek);
1683  }
1684 
1693  int getNumberOfFrames(const VideoStream& stream) const
1694  {
1695  int numOfFrames = -1;
1696  Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames);
1697  if (rc != STATUS_OK)
1698  {
1699  return 0;
1700  }
1701  return numOfFrames;
1702  }
1703 
1704  bool isValid() const
1705  {
1706  return m_pDevice != NULL;
1707  }
1708 private:
1709  Status attach(Device* device)
1710  {
1711  if (!device->isValid() || !device->isFile())
1712  {
1713  return STATUS_ERROR;
1714  }
1715 
1716  detach();
1717  m_pDevice = device;
1718 
1719  return STATUS_OK;
1720  }
1721  void detach()
1722  {
1723  m_pDevice = NULL;
1724  }
1725 
1726  friend class Device;
1727  PlaybackControl(Device* pDevice) : m_pDevice(NULL)
1728  {
1729  if (pDevice != NULL)
1730  {
1731  attach(pDevice);
1732  }
1733  }
1734 
1735  Device* m_pDevice;
1736 };
1737 
1739 {
1740 public:
1741  // setters
1743  {
1744  return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE);
1745  }
1747  {
1748  return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE);
1749  }
1750 
1752  {
1753  OniBool enabled = FALSE;
1754 
1755  Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled);
1756  return rc == STATUS_OK && enabled == TRUE;
1757  }
1759  {
1760  OniBool enabled = FALSE;
1761 
1762  Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled);
1763  return rc == STATUS_OK && enabled == TRUE;
1764  }
1765 
1766  bool isValid() const {return m_pStream != NULL;}
1767 private:
1768  template <class T>
1769  Status getProperty(int propertyId, T* value) const
1770  {
1771  if (!isValid()) return STATUS_NOT_SUPPORTED;
1772 
1773  return m_pStream->getProperty<T>(propertyId, value);
1774  }
1775  template <class T>
1776  Status setProperty(int propertyId, const T& value)
1777  {
1778  if (!isValid()) return STATUS_NOT_SUPPORTED;
1779 
1780  return m_pStream->setProperty<T>(propertyId, value);
1781  }
1782 
1783  friend class VideoStream;
1784  CameraSettings(VideoStream* pStream)
1785  {
1786  m_pStream = pStream;
1787  }
1788 
1789  VideoStream* m_pStream;
1790 };
1791 
1792 
1805 class OpenNI
1806 {
1807 public:
1808 
1825  {
1826  public:
1828  {
1829  m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback;
1830  m_deviceConnectedCallbacks.deviceDisconnected = NULL;
1831  m_deviceConnectedCallbacks.deviceStateChanged = NULL;
1832  m_deviceConnectedCallbacksHandle = NULL;
1833  }
1845  virtual void onDeviceConnected(const DeviceInfo*) = 0;
1846  private:
1847  static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie)
1848  {
1849  DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie;
1850  pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo));
1851  }
1852 
1853  friend class OpenNI;
1854  OniDeviceCallbacks m_deviceConnectedCallbacks;
1855  OniCallbackHandle m_deviceConnectedCallbacksHandle;
1856 
1857  };
1875  {
1876  public:
1878  {
1879  m_deviceDisconnectedCallbacks.deviceConnected = NULL;
1880  m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback;
1881  m_deviceDisconnectedCallbacks.deviceStateChanged = NULL;
1882  m_deviceDisconnectedCallbacksHandle = NULL;
1883  }
1892  virtual void onDeviceDisconnected(const DeviceInfo*) = 0;
1893  private:
1894  static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie)
1895  {
1897  pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo));
1898  }
1899 
1900  friend class OpenNI;
1901  OniDeviceCallbacks m_deviceDisconnectedCallbacks;
1902  OniCallbackHandle m_deviceDisconnectedCallbacksHandle;
1903  };
1918  {
1919  public:
1921  {
1922  m_deviceStateChangedCallbacks.deviceConnected = NULL;
1923  m_deviceStateChangedCallbacks.deviceDisconnected = NULL;
1924  m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback;
1925  m_deviceStateChangedCallbacksHandle = NULL;
1926  }
1933  virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0;
1934  private:
1935  static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie)
1936  {
1938  pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state));
1939  }
1940 
1941  friend class OpenNI;
1942  OniDeviceCallbacks m_deviceStateChangedCallbacks;
1943  OniCallbackHandle m_deviceStateChangedCallbacksHandle;
1944  };
1945 
1952  {
1953  return (Status)oniInitialize(ONI_API_VERSION); // provide version of API, to make sure proper struct sizes are used
1954  }
1955 
1960  static void shutdown()
1961  {
1962  oniShutdown();
1963  }
1964 
1969  {
1970  OniVersion version = oniGetVersion();
1971  union
1972  {
1973  OniVersion* pC;
1974  Version* pCpp;
1975  } a;
1976  a.pC = &version;
1977  return *a.pCpp;
1978  }
1979 
1987  static const char* getExtendedError()
1988  {
1989  return oniGetExtendedError();
1990  }
1991 
1996  static void enumerateDevices(Array<DeviceInfo>* deviceInfoList)
1997  {
1998  OniDeviceInfo* m_pDeviceInfos;
1999  int m_deviceInfoCount;
2000  oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount);
2001  deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true);
2002  oniReleaseDeviceList(m_pDeviceInfos);
2003  }
2004 
2013  static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER)
2014  {
2015  static const int ONI_MAX_STREAMS = 50;
2016  OniStreamHandle streams[ONI_MAX_STREAMS];
2017 
2018  if (streamCount > ONI_MAX_STREAMS)
2019  {
2020  printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS);
2021  return STATUS_BAD_PARAMETER;
2022  }
2023 
2024  *pReadyStreamIndex = -1;
2025  for (int i = 0; i < streamCount; ++i)
2026  {
2027  if (pStreams[i] != NULL)
2028  {
2029  streams[i] = pStreams[i]->_getHandle();
2030  }
2031  else
2032  {
2033  streams[i] = NULL;
2034  }
2035  }
2036  Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout);
2037 
2038  return rc;
2039  }
2040 
2049  {
2050  if (pListener->m_deviceConnectedCallbacksHandle != NULL)
2051  {
2052  return STATUS_ERROR;
2053  }
2054  return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle);
2055  }
2064  {
2065  if (pListener->m_deviceDisconnectedCallbacksHandle != NULL)
2066  {
2067  return STATUS_ERROR;
2068  }
2069  return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle);
2070  }
2079  {
2080  if (pListener->m_deviceStateChangedCallbacksHandle != NULL)
2081  {
2082  return STATUS_ERROR;
2083  }
2084  return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle);
2085  }
2094  {
2095  oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle);
2096  pListener->m_deviceConnectedCallbacksHandle = NULL;
2097  }
2106  {
2107  oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle);
2108  pListener->m_deviceDisconnectedCallbacksHandle = NULL;
2109  }
2118  {
2119  oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle);
2120  pListener->m_deviceStateChangedCallbacksHandle = NULL;
2121  }
2122 private:
2123  OpenNI()
2124  {
2125  }
2126 };
2127 
2164 {
2165 public:
2176  static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ)
2177  {
2178  float depthX, depthY, depthZ;
2179  Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ);
2180  *pDepthX = (int)depthX;
2181  *pDepthY = (int)depthY;
2182  *pDepthZ = (DepthPixel)depthZ;
2183  return rc;
2184  }
2185 
2196  static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ)
2197  {
2198  return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ);
2199  }
2200 
2211  static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ)
2212  {
2213  return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ);
2214  }
2215 
2226  static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ)
2227  {
2228  return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ);
2229  }
2230 
2242  static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY)
2243  {
2244  return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY);
2245  }
2246 };
2247 
2263 {
2264 public:
2269  Recorder() : m_recorder(NULL)
2270  {
2271  }
2272 
2277  {
2278  destroy();
2279  }
2280 
2292  Status create(const char* fileName)
2293  {
2294  if (!isValid())
2295  {
2296  return (Status)oniCreateRecorder(fileName, &m_recorder);
2297  }
2298  return STATUS_ERROR;
2299  }
2300 
2307  bool isValid() const
2308  {
2309  return NULL != getHandle();
2310  }
2311 
2322  Status attach(VideoStream& stream, bool allowLossyCompression = false)
2323  {
2324  if (!isValid() || !stream.isValid())
2325  {
2326  return STATUS_ERROR;
2327  }
2328  return (Status)oniRecorderAttachStream(
2329  m_recorder,
2330  stream._getHandle(),
2331  allowLossyCompression);
2332  }
2333 
2341  {
2342  if (!isValid())
2343  {
2344  return STATUS_ERROR;
2345  }
2346  return (Status)oniRecorderStart(m_recorder);
2347  }
2348 
2352  void stop()
2353  {
2354  if (isValid())
2355  {
2356  oniRecorderStop(m_recorder);
2357  }
2358  }
2359 
2363  void destroy()
2364  {
2365  if (isValid())
2366  {
2367  oniRecorderDestroy(&m_recorder);
2368  }
2369  }
2370 
2371 private:
2372  Recorder(const Recorder&);
2373  Recorder& operator=(const Recorder&);
2374 
2378  OniRecorderHandle getHandle() const
2379  {
2380  return m_recorder;
2381  }
2382 
2383 
2384  OniRecorderHandle m_recorder;
2385 };
2386 
2387 // Implemetation
2388 Status VideoStream::create(const Device& device, SensorType sensorType)
2389 {
2390  OniStreamHandle streamHandle;
2391  Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle);
2392  if (rc != STATUS_OK)
2393  {
2394  return rc;
2395  }
2396 
2397  _setHandle(streamHandle);
2398 
2399  if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE))
2400  {
2401  m_pCameraSettings = new CameraSettings(this);
2402  }
2403 
2404  return STATUS_OK;
2405 }
2406 
2408 {
2409  if (!isValid())
2410  {
2411  return;
2412  }
2413 
2414  if (m_pCameraSettings != NULL)
2415  {
2416  delete m_pCameraSettings;
2417  m_pCameraSettings = NULL;
2418  }
2419 
2420  if (m_stream != NULL)
2421  {
2422  oniStreamDestroy(m_stream);
2423  m_stream = NULL;
2424  }
2425 }
2426 
2427 Status Device::open(const char* uri)
2428 {
2429  OniDeviceHandle deviceHandle;
2430  Status rc = (Status)oniDeviceOpen(uri, &deviceHandle);
2431  if (rc != STATUS_OK)
2432  {
2433  return rc;
2434  }
2435 
2436  _setHandle(deviceHandle);
2437 
2438  if (isFile())
2439  {
2440  m_pPlaybackControl = new PlaybackControl(this);
2441  }
2442 
2443  return STATUS_OK;
2444 }
2445 
2447 {
2448  if (m_pPlaybackControl != NULL)
2449  {
2450  delete m_pPlaybackControl;
2451  m_pPlaybackControl = NULL;
2452  }
2453 
2454  if (m_device != NULL)
2455  {
2456  oniDeviceClose(m_device);
2457  m_device = NULL;
2458  }
2459 }
2460 
2461 
2462 }
2463 
2464 #endif // _OPEN_NI_HPP_