IFrameDescription* Kinect2StreamImpl::getFrameDescription(OniSensorType sensorType)
{
  if (!m_pKinectSensor) {
    return NULL;
  }

  IFrameDescription* frameDescription = NULL;
  if (sensorType == ONI_SENSOR_COLOR) {
    IColorFrameSource* frameSource = NULL;
    HRESULT hr = m_pKinectSensor->get_ColorFrameSource(&frameSource);
    if (SUCCEEDED(hr)) {
      hr = frameSource->get_FrameDescription(&frameDescription);
      if (FAILED(hr) && frameDescription) {
        frameDescription->Release();
        frameDescription = NULL;
      }
    }
    if (frameSource) {
      frameSource->Release();
    }
  }
  else if (sensorType == ONI_SENSOR_DEPTH) {
    IDepthFrameSource* frameSource = NULL;
    HRESULT hr = m_pKinectSensor->get_DepthFrameSource(&frameSource);
    if (SUCCEEDED(hr)) {
      hr = frameSource->get_FrameDescription(&frameDescription);
      if (FAILED(hr) && frameDescription) {
        frameDescription->Release();
        frameDescription = NULL;
      }
    }
    if (frameSource) {
      frameSource->Release();
    }
  }
  else { // ONI_SENSOR_IR
    IInfraredFrameSource* frameSource = NULL;
    HRESULT hr = m_pKinectSensor->get_InfraredFrameSource(&frameSource);
    if (SUCCEEDED(hr)) {
      hr = frameSource->get_FrameDescription(&frameDescription);
      if (FAILED(hr) && frameDescription) {
        frameDescription->Release();
        frameDescription = NULL;
      }
    }
    if (frameSource) {
      frameSource->Release();
    }
  }

  return frameDescription;
}
void Kinect2StreamImpl::openFrameReader()
{
  if (!m_pKinectSensor) {
    return;
  }

  if (m_sensorType == ONI_SENSOR_COLOR && !m_pFrameReader.color) {
    IColorFrameSource* frameSource = NULL;
    HRESULT hr = m_pKinectSensor->get_ColorFrameSource(&frameSource);
    if (SUCCEEDED(hr)) {
      hr = frameSource->OpenReader(&m_pFrameReader.color);
      if (FAILED(hr) && m_pFrameReader.color) {
        m_pFrameReader.color->Release();
        m_pFrameReader.color = NULL;
      }
    }
    if (frameSource) {
      frameSource->Release();
    }
  }
  else if (m_sensorType == ONI_SENSOR_DEPTH && !m_pFrameReader.depth) {
    IDepthFrameSource* frameSource = NULL;
    HRESULT hr = m_pKinectSensor->get_DepthFrameSource(&frameSource);
    if (SUCCEEDED(hr)) {
      hr = frameSource->OpenReader(&m_pFrameReader.depth);
      if (FAILED(hr) && m_pFrameReader.depth) {
        m_pFrameReader.depth->Release();
        m_pFrameReader.depth = NULL;
      }
    }
    if (frameSource) {
      frameSource->Release();
    }
  }
  else if(!m_pFrameReader.infrared) { // ONI_SENSOR_IR
    IInfraredFrameSource* frameSource = NULL;
    HRESULT hr = m_pKinectSensor->get_InfraredFrameSource(&frameSource);
    if (SUCCEEDED(hr)) {
      hr = frameSource->OpenReader(&m_pFrameReader.infrared);
      if (FAILED(hr) && m_pFrameReader.infrared) {
        m_pFrameReader.infrared->Release();
        m_pFrameReader.infrared = NULL;
      }
    }
    if (frameSource) {
      frameSource->Release();
    }
  }
}
int main(int argc, char** argv)
{
	// 1a. Get default Sensor
	cout << "Try to get default sensor" << endl;
	IKinectSensor* pSensor = nullptr;
	if (GetDefaultKinectSensor(&pSensor) != S_OK)
	{
		cerr << "Get Sensor failed" << endl;
		return -1;
	}

	// 1b. Open sensor
	cout << "Try to open sensor" << endl;
	if (pSensor->Open() != S_OK)
	{
		cerr << "Can't open sensor" << endl;
		return -1;
	}

	// 2a. Get frame source
	cout << "Try to get Infrared source" << endl;
	IInfraredFrameSource* pFrameSource = nullptr;
	if (pSensor->get_InfraredFrameSource(&pFrameSource) != S_OK)
	{
		cerr << "Can't get Infrared frame source" << endl;
		return -1;
	}

	// 2b. Get frame description
	cout << "get Infrared frame description" << endl;
	int		iWidth = 0;
	int		iHeight = 0;
	IFrameDescription* pFrameDescription = nullptr;
	if (pFrameSource->get_FrameDescription(&pFrameDescription) == S_OK)
	{
		pFrameDescription->get_Width(&iWidth);
		pFrameDescription->get_Height(&iHeight);
	}
	pFrameDescription->Release();
	pFrameDescription = nullptr;

	// 3a. get frame reader
	cout << "Try to get Infrared frame reader" << endl;
	IInfraredFrameReader* pFrameReader = nullptr;
	if (pFrameSource->OpenReader(&pFrameReader) != S_OK)
	{
		cerr << "Can't get Infrared frame reader" << endl;
		return -1;
	}

	// 2c. release Frame source
	cout << "Release frame source" << endl;
	pFrameSource->Release();
	pFrameSource = nullptr;

	// create OpenCV window
	cv::namedWindow( "Infrared Image" );

	// Enter main loop
	while (true)
	{
		// 4a. Get last frame
		IInfraredFrame* pFrame = nullptr;
		if (pFrameReader->AcquireLatestFrame(&pFrame) == S_OK)
		{
			// 4c. Copy to OpenCV image
			UINT	uSize = 0;
			UINT16*	pBuffer = nullptr;
			if (pFrame->AccessUnderlyingBuffer(&uSize, &pBuffer) == S_OK)
			{
				cv::Mat mIRImg(iHeight, iWidth, CV_16UC1, pBuffer);
				cv::imshow("Infrared Image", mIRImg);
			}
			else
			{
				cerr << "Data access error" << endl;
			}

			// 4e. release frame
			pFrame->Release();
		}

		// 4f. check keyboard input
		if (cv::waitKey(30) == VK_ESCAPE){
			break;
		}
	}

	// 3b. release frame reader
	cout << "Release frame reader" << endl;
	pFrameReader->Release();
	pFrameReader = nullptr;

	// 1c. Close Sensor
	cout << "close sensor" << endl;
	pSensor->Close();

	// 1d. Release Sensor
	cout << "Release sensor" << endl;
	pSensor->Release();
	pSensor = nullptr;

	return 0;
}