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 
156 class VideoMode : private OniVideoMode
157 {
158 public:
165  {}
166 
172  VideoMode(const VideoMode& other)
173  {
174  *this = other;
175  }
176 
184  {
186  setResolution(other.getResolutionX(), other.getResolutionY());
187  setFps(other.getFps());
188 
189  return *this;
190  }
191 
196  PixelFormat getPixelFormat() const { return (PixelFormat)pixelFormat; }
197 
202  int getResolutionX() const { return resolutionX; }
203 
208  int getResolutionY() const {return resolutionY;}
209 
214  int getFps() const { return fps; }
215 
222  void setPixelFormat(PixelFormat format) { this->pixelFormat = (OniPixelFormat)format; }
223 
231  void setResolution(int resolutionX, int resolutionY)
232  {
233  this->resolutionX = resolutionX;
234  this->resolutionY = resolutionY;
235  }
236 
243  void setFps(int fps) { this->fps = fps; }
244 
245  friend class SensorInfo;
246  friend class VideoStream;
247  friend class VideoFrameRef;
248 };
249 
268 {
269 public:
274  SensorType getSensorType() const { return (SensorType)m_pInfo->sensorType; }
275 
283  const Array<VideoMode>& getSupportedVideoModes() const { return m_videoModes; }
284 
285 private:
286  SensorInfo(const SensorInfo&);
287  SensorInfo& operator=(const SensorInfo&);
288 
289  SensorInfo() : m_pInfo(NULL), m_videoModes(NULL, 0) {}
290 
291  SensorInfo(const OniSensorInfo* pInfo) : m_pInfo(NULL), m_videoModes(NULL, 0)
292  {
293  _setInternal(pInfo);
294  }
295 
296  void _setInternal(const OniSensorInfo* pInfo)
297  {
298  m_pInfo = pInfo;
299  if (pInfo == NULL)
300  {
301  m_videoModes._setData(NULL, 0);
302  }
303  else
304  {
305  m_videoModes._setData(static_cast<VideoMode*>(pInfo->pSupportedVideoModes), pInfo->numSupportedVideoModes);
306  }
307  }
308 
309  const OniSensorInfo* m_pInfo;
310  Array<VideoMode> m_videoModes;
311 
312  friend class VideoStream;
313  friend class Device;
314 };
315 
325 class DeviceInfo : private OniDeviceInfo
326 {
327 public:
332  const char* getUri() const { return uri; }
334  const char* getVendor() const { return vendor; }
336  const char* getName() const { return name; }
338  uint16_t getUsbVendorId() const { return usbVendorId; }
340  uint16_t getUsbProductId() const { return usbProductId; }
341 
342  friend class Device;
343  friend class OpenNI;
344 };
345 
360 {
361 public:
367  {
368  m_pFrame = NULL;
369  }
370 
375  {
376  release();
377  }
378 
384  VideoFrameRef(const VideoFrameRef& other) : m_pFrame(NULL)
385  {
386  _setFrame(other.m_pFrame);
387  }
388 
395  {
396  _setFrame(other.m_pFrame);
397  return *this;
398  }
399 
405  inline int getDataSize() const
406  {
407  return m_pFrame->dataSize;
408  }
409 
415  inline const void* getData() const
416  {
417  return m_pFrame->data;
418  }
419 
426  inline SensorType getSensorType() const
427  {
428  return (SensorType)m_pFrame->sensorType;
429  }
430 
438  inline const VideoMode& getVideoMode() const
439  {
440  return static_cast<const VideoMode&>(m_pFrame->videoMode);
441  }
442 
450  inline uint64_t getTimestamp() const
451  {
452  return m_pFrame->timestamp;
453  }
454 
465  inline int getFrameIndex() const
466  {
467  return m_pFrame->frameIndex;
468  }
469 
476  inline int getWidth() const
477  {
478  return m_pFrame->width;
479  }
480 
486  inline int getHeight() const
487  {
488  return m_pFrame->height;
489  }
490 
495  inline bool getCroppingEnabled() const
496  {
497  return m_pFrame->croppingEnabled == TRUE;
498  }
499 
504  inline int getCropOriginX() const
505  {
506  return m_pFrame->cropOriginX;
507  }
508 
513  inline int getCropOriginY() const
514  {
515  return m_pFrame->cropOriginY;
516  }
517 
523  inline int getStrideInBytes() const
524  {
525  return m_pFrame->stride;
526  }
527 
531  inline bool isValid() const
532  {
533  return m_pFrame != NULL;
534  }
535 
540  void release()
541  {
542  if (m_pFrame != NULL)
543  {
544  oniFrameRelease(m_pFrame);
545  m_pFrame = NULL;
546  }
547  }
548 
550  void _setFrame(OniFrame* pFrame)
551  {
552  setReference(pFrame);
553  if (pFrame != NULL)
554  {
555  oniFrameAddRef(pFrame);
556  }
557  }
558 
560  OniFrame* _getFrame()
561  {
562  return m_pFrame;
563  }
564 
565 private:
566  friend class VideoStream;
567  inline void setReference(OniFrame* pFrame)
568  {
569  // Initial - don't addref. This is the reference from OpenNI
570  release();
571  m_pFrame = pFrame;
572  }
573 
574  OniFrame* m_pFrame; // const!!?
575 };
576 
577 
578 class Device;
579 
601 class CameraSettings;
602 
604 {
605 public:
614  {
615  public:
619  NewFrameListener() : m_callbackHandle(NULL)
620  {
621  }
622 
626  virtual void onNewFrame(VideoStream&) = 0;
627 
628  private:
629  friend class VideoStream;
630 
631  static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie)
632  {
633  NewFrameListener* pListener = (NewFrameListener*)pCookie;
634  VideoStream stream;
635  stream._setHandle(streamHandle);
636  pListener->onNewFrame(stream);
637  stream._setHandle(NULL);
638  }
639  OniCallbackHandle m_callbackHandle;
640  };
641 
646  VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL)
647  {}
648 
654  {
655  destroy();
656  }
657 
662  bool isValid() const
663  {
664  return m_stream != NULL;
665  }
666 
676  inline Status create(const Device& device, SensorType sensorType);
677 
683  inline void destroy();
684 
693  const SensorInfo& getSensorInfo() const
694  {
695  return m_sensorInfo;
696  }
697 
702  {
703  if (!isValid())
704  {
705  return STATUS_ERROR;
706  }
707 
708  return (Status)oniStreamStart(m_stream);
709  }
710 
714  void stop()
715  {
716  if (!isValid())
717  {
718  return;
719  }
720 
721  oniStreamStop(m_stream);
722  }
723 
735  {
736  if (!isValid())
737  {
738  return STATUS_ERROR;
739  }
740 
741  OniFrame* pOniFrame;
742  Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame);
743 
744  pFrame->setReference(pOniFrame);
745  return rc;
746  }
747 
756  {
757  if (!isValid())
758  {
759  return STATUS_ERROR;
760  }
761  if (pListener->m_callbackHandle != NULL)
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 
1129 class PlaybackControl;
1130 
1147 class Device
1148 {
1149 public:
1154  Device() : m_pPlaybackControl(NULL), m_device(NULL)
1155  {
1156  clearSensors();
1157  }
1158 
1164  {
1165  if (m_device != NULL)
1166  {
1167  close();
1168  }
1169  }
1170 
1200  inline Status open(const char* uri);
1201 
1207  inline void close();
1208 
1218  const DeviceInfo& getDeviceInfo() const
1219  {
1220  return m_deviceInfo;
1221  }
1222 
1230  bool hasSensor(SensorType sensorType)
1231  {
1232  int i;
1233  for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i)
1234  {
1235  if (m_aSensorInfo[i].getSensorType() == sensorType)
1236  {
1237  return true;
1238  }
1239  }
1240 
1241  if (i == ONI_MAX_SENSORS)
1242  {
1243  return false;
1244  }
1245 
1246  const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType);
1247 
1248  if (pInfo == NULL)
1249  {
1250  return false;
1251  }
1252 
1253  m_aSensorInfo[i]._setInternal(pInfo);
1254 
1255  return true;
1256  }
1257 
1266  {
1267  int i;
1268  for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i)
1269  {
1270  if (m_aSensorInfo[i].getSensorType() == sensorType)
1271  {
1272  return &m_aSensorInfo[i];
1273  }
1274  }
1275 
1276  // not found. check to see we have additional space
1277  if (i == ONI_MAX_SENSORS)
1278  {
1279  return NULL;
1280  }
1281 
1282  const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType);
1283  if (pInfo == NULL)
1284  {
1285  return NULL;
1286  }
1287 
1288  m_aSensorInfo[i]._setInternal(pInfo);
1289  return &m_aSensorInfo[i];
1290  }
1291 
1296  OniDeviceHandle _getHandle() const
1297  {
1298  return m_device;
1299  }
1300 
1305  PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;}
1306 
1318  Status getProperty(int propertyId, void* data, int* dataSize) const
1319  {
1320  return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize);
1321  }
1322 
1334  Status setProperty(int propertyId, const void* data, int dataSize)
1335  {
1336  return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize);
1337  }
1338 
1347  {
1348  return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE);
1349  }
1350 
1359  {
1360  ImageRegistrationMode mode;
1361  Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode);
1362  if (rc != STATUS_OK)
1363  {
1364  return IMAGE_REGISTRATION_OFF;
1365  }
1366  return mode;
1367  }
1368 
1383  {
1384  return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode);
1385  }
1386 
1391  bool isValid() const
1392  {
1393  return m_device != NULL;
1394  }
1395 
1400  bool isFile() const
1401  {
1402  return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) &&
1403  isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) &&
1404  isCommandSupported(DEVICE_COMMAND_SEEK);
1405  }
1406 
1416  {
1417  Status rc = STATUS_OK;
1418 
1419  if (isEnabled)
1420  {
1421  rc = (Status)oniDeviceEnableDepthColorSync(m_device);
1422  }
1423  else
1424  {
1425  oniDeviceDisableDepthColorSync(m_device);
1426  }
1427 
1428  return rc;
1429  }
1430 
1441  template <class T>
1442  Status setProperty(int propertyId, const T& value)
1443  {
1444  return setProperty(propertyId, &value, sizeof(T));
1445  }
1446 
1456  template <class T>
1457  Status getProperty(int propertyId, T* value) const
1458  {
1459  int size = sizeof(T);
1460  return getProperty(propertyId, value, &size);
1461  }
1462 
1468  bool isPropertySupported(int propertyId) const
1469  {
1470  return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE;
1471  }
1472 
1482  Status invoke(int commandId, const void* data, int dataSize)
1483  {
1484  return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize);
1485  }
1486 
1496  template <class T>
1497  Status invoke(int propertyId, const T& value)
1498  {
1499  return invoke(propertyId, &value, sizeof(T));
1500  }
1501 
1507  bool isCommandSupported(int commandId) const
1508  {
1509  return oniDeviceIsCommandSupported(m_device, commandId) == TRUE;
1510  }
1511 
1512 private:
1513  Device(const Device&);
1514  Device& operator=(const Device&);
1515 
1516  void clearSensors()
1517  {
1518  for (int i = 0; i < ONI_MAX_SENSORS; ++i)
1519  {
1520  m_aSensorInfo[i]._setInternal(NULL);
1521  }
1522  }
1523 
1524  Status _setHandle(OniDeviceHandle deviceHandle)
1525  {
1526  if (m_device == NULL)
1527  {
1528  m_device = deviceHandle;
1529 
1530  clearSensors();
1531 
1532  oniDeviceGetInfo(m_device, &m_deviceInfo);
1533  // Read deviceInfo
1534  return STATUS_OK;
1535  }
1536 
1537  return STATUS_OUT_OF_FLOW;
1538  }
1539 
1540 private:
1541  PlaybackControl* m_pPlaybackControl;
1542 
1543  OniDeviceHandle m_device;
1544  DeviceInfo m_deviceInfo;
1545  SensorInfo m_aSensorInfo[ONI_MAX_SENSORS];
1546 };
1547 
1562 {
1563 public:
1564 
1571  {
1572  detach();
1573  }
1574 
1595  float getSpeed() const
1596  {
1597  if (!isValid())
1598  {
1599  return 0.0f;
1600  }
1601  float speed;
1602  Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed);
1603  if (rc != STATUS_OK)
1604  {
1605  return 1.0f;
1606  }
1607  return speed;
1608  }
1616  Status setSpeed(float speed)
1617  {
1618  if (!isValid())
1619  {
1620  return STATUS_NO_DEVICE;
1621  }
1622  return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed);
1623  }
1624 
1630  bool getRepeatEnabled() const
1631  {
1632  if (!isValid())
1633  {
1634  return false;
1635  }
1636 
1637  OniBool repeat;
1638  Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat);
1639  if (rc != STATUS_OK)
1640  {
1641  return false;
1642  }
1643 
1644  return repeat == TRUE;
1645  }
1646 
1656  {
1657  if (!isValid())
1658  {
1659  return STATUS_NO_DEVICE;
1660  }
1661 
1662  return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE);
1663  }
1664 
1675  Status seek(const VideoStream& stream, int frameIndex)
1676  {
1677  if (!isValid())
1678  {
1679  return STATUS_NO_DEVICE;
1680  }
1681  OniSeek seek;
1682  seek.frameIndex = frameIndex;
1683  seek.stream = stream._getHandle();
1684  return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek);
1685  }
1686 
1695  int getNumberOfFrames(const VideoStream& stream) const
1696  {
1697  int numOfFrames = -1;
1698  Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames);
1699  if (rc != STATUS_OK)
1700  {
1701  return 0;
1702  }
1703  return numOfFrames;
1704  }
1705 
1706  bool isValid() const
1707  {
1708  return m_pDevice != NULL;
1709  }
1710 private:
1711  Status attach(Device* device)
1712  {
1713  if (!device->isValid() || !device->isFile())
1714  {
1715  return STATUS_ERROR;
1716  }
1717 
1718  detach();
1719  m_pDevice = device;
1720 
1721  return STATUS_OK;
1722  }
1723  void detach()
1724  {
1725  m_pDevice = NULL;
1726  }
1727 
1728  friend class Device;
1729  PlaybackControl(Device* pDevice) : m_pDevice(NULL)
1730  {
1731  if (pDevice != NULL)
1732  {
1733  attach(pDevice);
1734  }
1735  }
1736 
1737  Device* m_pDevice;
1738 };
1739 
1741 {
1742 public:
1743  // setters
1745  {
1746  return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE);
1747  }
1749  {
1750  return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE);
1751  }
1752 
1754  {
1755  OniBool enabled = FALSE;
1756 
1757  Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled);
1758  return rc == STATUS_OK && enabled == TRUE;
1759  }
1761  {
1762  OniBool enabled = FALSE;
1763 
1764  Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled);
1765  return rc == STATUS_OK && enabled == TRUE;
1766  }
1767 
1768  bool isValid() const {return m_pStream != NULL;}
1769 private:
1770  template <class T>
1771  Status getProperty(int propertyId, T* value) const
1772  {
1773  if (!isValid()) return STATUS_NOT_SUPPORTED;
1774 
1775  return m_pStream->getProperty<T>(propertyId, value);
1776  }
1777  template <class T>
1778  Status setProperty(int propertyId, const T& value)
1779  {
1780  if (!isValid()) return STATUS_NOT_SUPPORTED;
1781 
1782  return m_pStream->setProperty<T>(propertyId, value);
1783  }
1784 
1785  friend class VideoStream;
1786  CameraSettings(VideoStream* pStream)
1787  {
1788  m_pStream = pStream;
1789  }
1790 
1791  VideoStream* m_pStream;
1792 };
1793 
1794 
1807 class OpenNI
1808 {
1809 public:
1810 
1827  {
1828  public:
1830  {
1831  m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback;
1832  m_deviceConnectedCallbacks.deviceDisconnected = NULL;
1833  m_deviceConnectedCallbacks.deviceStateChanged = NULL;
1834  m_deviceConnectedCallbacksHandle = NULL;
1835  }
1847  virtual void onDeviceConnected(const DeviceInfo*) = 0;
1848  private:
1849  static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie)
1850  {
1851  DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie;
1852  pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo));
1853  }
1854 
1855  friend class OpenNI;
1856  OniDeviceCallbacks m_deviceConnectedCallbacks;
1857  OniCallbackHandle m_deviceConnectedCallbacksHandle;
1858 
1859  };
1877  {
1878  public:
1880  {
1881  m_deviceDisconnectedCallbacks.deviceConnected = NULL;
1882  m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback;
1883  m_deviceDisconnectedCallbacks.deviceStateChanged = NULL;
1884  m_deviceDisconnectedCallbacksHandle = NULL;
1885  }
1894  virtual void onDeviceDisconnected(const DeviceInfo*) = 0;
1895  private:
1896  static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie)
1897  {
1899  pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo));
1900  }
1901 
1902  friend class OpenNI;
1903  OniDeviceCallbacks m_deviceDisconnectedCallbacks;
1904  OniCallbackHandle m_deviceDisconnectedCallbacksHandle;
1905  };
1920  {
1921  public:
1923  {
1924  m_deviceStateChangedCallbacks.deviceConnected = NULL;
1925  m_deviceStateChangedCallbacks.deviceDisconnected = NULL;
1926  m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback;
1927  m_deviceStateChangedCallbacksHandle = NULL;
1928  }
1935  virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0;
1936  private:
1937  static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie)
1938  {
1940  pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state));
1941  }
1942 
1943  friend class OpenNI;
1944  OniDeviceCallbacks m_deviceStateChangedCallbacks;
1945  OniCallbackHandle m_deviceStateChangedCallbacksHandle;
1946  };
1947 
1954  {
1955  return (Status)oniInitialize(ONI_API_VERSION); // provide version of API, to make sure proper struct sizes are used
1956  }
1957 
1962  static void shutdown()
1963  {
1964  oniShutdown();
1965  }
1966 
1971  {
1972  OniVersion version = oniGetVersion();
1973  union
1974  {
1975  OniVersion* pC;
1976  Version* pCpp;
1977  } a;
1978  a.pC = &version;
1979  return *a.pCpp;
1980  }
1981 
1989  static const char* getExtendedError()
1990  {
1991  return oniGetExtendedError();
1992  }
1993 
1998  static void enumerateDevices(Array<DeviceInfo>* deviceInfoList)
1999  {
2000  OniDeviceInfo* m_pDeviceInfos;
2001  int m_deviceInfoCount;
2002  oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount);
2003  deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true);
2004  oniReleaseDeviceList(m_pDeviceInfos);
2005  }
2006 
2015  static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER)
2016  {
2017  static const int ONI_MAX_STREAMS = 50;
2018  OniStreamHandle streams[ONI_MAX_STREAMS];
2019 
2020  if (streamCount > ONI_MAX_STREAMS)
2021  {
2022  printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS);
2023  return STATUS_BAD_PARAMETER;
2024  }
2025 
2026  *pReadyStreamIndex = -1;
2027  for (int i = 0; i < streamCount; ++i)
2028  {
2029  if (pStreams[i] != NULL)
2030  {
2031  streams[i] = pStreams[i]->_getHandle();
2032  }
2033  else
2034  {
2035  streams[i] = NULL;
2036  }
2037  }
2038  Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout);
2039 
2040  return rc;
2041  }
2042 
2051  {
2052  if (pListener->m_deviceConnectedCallbacksHandle != NULL)
2053  {
2054  return STATUS_ERROR;
2055  }
2056  return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle);
2057  }
2066  {
2067  if (pListener->m_deviceDisconnectedCallbacksHandle != NULL)
2068  {
2069  return STATUS_ERROR;
2070  }
2071  return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle);
2072  }
2081  {
2082  if (pListener->m_deviceStateChangedCallbacksHandle != NULL)
2083  {
2084  return STATUS_ERROR;
2085  }
2086  return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle);
2087  }
2096  {
2097  oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle);
2098  pListener->m_deviceConnectedCallbacksHandle = NULL;
2099  }
2108  {
2109  oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle);
2110  pListener->m_deviceDisconnectedCallbacksHandle = NULL;
2111  }
2120  {
2121  oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle);
2122  pListener->m_deviceStateChangedCallbacksHandle = NULL;
2123  }
2124 private:
2125  OpenNI()
2126  {
2127  }
2128 };
2129 
2166 {
2167 public:
2178  static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ)
2179  {
2180  float depthX, depthY, depthZ;
2181  Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ);
2182  *pDepthX = (int)depthX;
2183  *pDepthY = (int)depthY;
2184  *pDepthZ = (DepthPixel)depthZ;
2185  return rc;
2186  }
2187 
2198  static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ)
2199  {
2200  return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ);
2201  }
2202 
2213  static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ)
2214  {
2215  return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ);
2216  }
2217 
2228  static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ)
2229  {
2230  return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ);
2231  }
2232 
2244  static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY)
2245  {
2246  return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY);
2247  }
2248 };
2249 
2265 {
2266 public:
2271  Recorder() : m_recorder(NULL)
2272  {
2273  }
2274 
2279  {
2280  destroy();
2281  }
2282 
2294  Status create(const char* fileName)
2295  {
2296  if (!isValid())
2297  {
2298  return (Status)oniCreateRecorder(fileName, &m_recorder);
2299  }
2300  return STATUS_ERROR;
2301  }
2302 
2309  bool isValid() const
2310  {
2311  return NULL != getHandle();
2312  }
2313 
2324  Status attach(VideoStream& stream, bool allowLossyCompression = false)
2325  {
2326  if (!isValid() || !stream.isValid())
2327  {
2328  return STATUS_ERROR;
2329  }
2330  return (Status)oniRecorderAttachStream(
2331  m_recorder,
2332  stream._getHandle(),
2333  allowLossyCompression);
2334  }
2335 
2343  {
2344  if (!isValid())
2345  {
2346  return STATUS_ERROR;
2347  }
2348  return (Status)oniRecorderStart(m_recorder);
2349  }
2350 
2354  void stop()
2355  {
2356  if (isValid())
2357  {
2358  oniRecorderStop(m_recorder);
2359  }
2360  }
2361 
2365  void destroy()
2366  {
2367  if (isValid())
2368  {
2369  oniRecorderDestroy(&m_recorder);
2370  }
2371  }
2372 
2373 private:
2374  Recorder(const Recorder&);
2375  Recorder& operator=(const Recorder&);
2376 
2380  OniRecorderHandle getHandle() const
2381  {
2382  return m_recorder;
2383  }
2384 
2385 
2386  OniRecorderHandle m_recorder;
2387 };
2388 
2389 // Implemetation
2390 Status VideoStream::create(const Device& device, SensorType sensorType)
2391 {
2392  OniStreamHandle streamHandle;
2393  Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle);
2394  if (rc != STATUS_OK)
2395  {
2396  return rc;
2397  }
2398 
2399  _setHandle(streamHandle);
2400 
2401  if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE))
2402  {
2403  m_pCameraSettings = new CameraSettings(this);
2404  }
2405 
2406  return STATUS_OK;
2407 }
2408 
2410 {
2411  if (!isValid())
2412  {
2413  return;
2414  }
2415 
2416  if (m_pCameraSettings != NULL)
2417  {
2418  delete m_pCameraSettings;
2419  m_pCameraSettings = NULL;
2420  }
2421 
2422  if (m_stream != NULL)
2423  {
2424  oniStreamDestroy(m_stream);
2425  m_stream = NULL;
2426  }
2427 }
2428 
2429 Status Device::open(const char* uri)
2430 {
2431  OniDeviceHandle deviceHandle;
2432  Status rc = (Status)oniDeviceOpen(uri, &deviceHandle);
2433  if (rc != STATUS_OK)
2434  {
2435  return rc;
2436  }
2437 
2438  _setHandle(deviceHandle);
2439 
2440  if (isFile())
2441  {
2442  m_pPlaybackControl = new PlaybackControl(this);
2443  }
2444 
2445  return STATUS_OK;
2446 }
2447 
2449 {
2450  if (m_pPlaybackControl != NULL)
2451  {
2452  delete m_pPlaybackControl;
2453  m_pPlaybackControl = NULL;
2454  }
2455 
2456  if (m_device != NULL)
2457  {
2458  oniDeviceClose(m_device);
2459  m_device = NULL;
2460  }
2461 }
2462 
2463 
2464 }
2465 
2466 #endif // _OPEN_NI_HPP_