/***************************************************************************** * * * PrimeSense Sensor 5.0 Alpha * * Copyright (C) 2010 PrimeSense Ltd. * * * * This file is part of PrimeSense Common. * * * * PrimeSense Sensor is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published * * by the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * PrimeSense Sensor is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with PrimeSense Sensor. If not, see . * * * *****************************************************************************/ #include "XnFileDevice.h" #include "XnDeviceFileReaderBC.h" #include #include #include //--------------------------------------------------------------------------- // Backwards Compatibility //--------------------------------------------------------------------------- extern XnStatus XnIOAdjustStreamPropertiesV3(const XnStreamProperties* pStreamPropertiesV3, XnStreamProperties* pStreamProperties); extern XnStatus XnIOAdjustStreamPropertiesV2 (const XnStreamPropertiesV2* pStreamPropertiesV2, XnStreamProperties* pStreamProperties); extern XnStatus XnIOAdjustStreamPropertiesV1 (const XnStreamPropertiesV1* pStreamPropertiesV1, XnStreamProperties* pStreamProperties); extern XnStatus XnIOAdjustStreamFramePropertiesV3(const XnStreamFrameProperties* pStreamFramePropertiesV3, XnStreamFrameProperties* pStreamFrameProperties); extern XnStatus XnIOAdjustStreamFramePropertiesV2 (const XnStreamFramePropertiesV2* pStreamFramePropertiesV2, XnStreamFrameProperties* pStreamFrameProperties); extern XnStatus XnIOAdjustStreamFramePropertiesV1 (const XnStreamFramePropertiesV1* pStreamFramePropertiesV1, XnStreamFrameProperties* pStreamFrameProperties); extern XnStatus XnIOAdjustPackedStreamPropertiesV2 (const XnPackedStreamPropertiesV2* pPackedStreamPropertiesV2, XnPackedStreamProperties* pPackedStreamProperties); extern XnStatus XnIOAdjustPackedStreamFrameHeaderV2 (const XnPackedStreamFrameHeaderV2* pPackedStreamFrameHeaderV2, XnPackedStreamFrameHeaderV3* pPackedStreamFrameHeader); extern XnStatus XnIOAdjustPackedStreamPropertiesV1 (const XnPackedStreamPropertiesV1* pPackedStreamPropertiesV1, XnPackedStreamProperties* pPackedStreamProperties); extern XnStatus XnIOAdjustPackedStreamFrameHeaderV1 (const XnPackedStreamFrameHeaderV1* pPackedStreamFrameHeaderV1, XnPackedStreamFrameHeaderV3* pPackedStreamFrameHeader); extern XnStatus XnIOAdjustPackedStreamPropertiesV3 (const XnPackedStreamProperties* pPackedStreamPropertiesV3, XnPackedStreamProperties* pPackedStreamProperties); extern XnStatus XnIOAdjustPackedStreamFrameHeaderV3 (const XnPackedStreamFrameHeaderV3* pPackedStreamFrameHeaderV3, XnPackedStreamFrameHeaderV3* pPackedStreamFrameHeader); extern XnStatus BCSetDepthProperties(XnPropertySet* pSet, XnStreamPropertiesV3* pStreamProperties, XnPackedStreamProperties* pPackedStreamProperties); extern XnStatus BCSetImageProperties(XnPropertySet* pSet, XnStreamPropertiesV3* pStreamProperties, XnPackedStreamProperties* pPackedStreamProperties); extern XnStatus BCSetAudioProperties(XnPropertySet* pSet, XnStreamPropertiesV3* pStreamProperties, XnPackedStreamProperties* pPackedStreamProperties); extern XnStatus ConvertStreamPropertiesToPropertySet(XnStreamPropertiesV3* pStreamProperties, XnPackedStreamProperties* pPackedStreamProperties, XnPropertySet* pSet); extern XnStatus XnDeviceFileAdjustFileFrameHeaderV1(const XnDeviceFileFrameHeaderV1* pFileFrameHeaderV1, XnDeviceFileFrameHeaderV3* pFileFrameHeader); extern XnStatus XnDeviceFileAdjustFileFrameHeaderV2(const XnDeviceFileFrameHeaderV2* pFileFrameHeaderV2, XnDeviceFileFrameHeaderV3* pFileFrameHeader); extern XnStatus XnDeviceFileAdjustFileFrameHeaderV3(const XnDeviceFileFrameHeaderV3* pFileFrameHeaderV3, XnDeviceFileFrameHeaderV3* pFileFrameHeader); XnStatus XnFileDevice::BCInit() { XN_VALIDATE_CALLOC(m_pBCData, XnFileBCData, 1); return XN_STATUS_OK; } XnStatus XnFileDevice::BCCalculatePackedBufferSize() { XnStatus nRetVal = XN_STATUS_OK; XnStreamPropertiesV3* pStreamProperties = &m_pBCData->StreamProperties; XnPackedStreamProperties* pPackedStreamProperties = &m_pBCData->PackedStreamProperties; XnUInt32 nBufferSize = 0; if (pStreamProperties->DepthFormat != XN_DEPTH_FORMAT_DISABLED) { if ((pStreamProperties->DepthFormat == XN_DEPTH_FORMAT_RAW12) || (pStreamProperties->DepthFormat == XN_DEPTH_FORMAT_RAW10) || (pStreamProperties->DepthFormat == XN_DEPTH_FORMAT_SHIFTS)) { switch (pPackedStreamProperties->StreamDepthCompressionFormat) { case XN_COMPRESSED_DEPTH_FORMAT_SKIP: break; case XN_COMPRESSED_DEPTH_FORMAT_UNCOMPRESSED: nBufferSize += pStreamProperties->nDepthBufferSize; break; case XN_COMPRESSED_DEPTH_FORMAT_16Z: case XN_COMPRESSED_DEPTH_FORMAT_16ZEMBTABLE: nBufferSize += (XnUInt32)(pStreamProperties->nDepthBufferSize * XN_STREAM_COMPRESSION_DEPTH16Z_WORSE_RATIO); break; default: return (XN_STATUS_IO_INVALID_STREAM_DEPTH_COMPRESSION_FORMAT); } } else { return (XN_STATUS_IO_INVALID_STREAM_DEPTH_FORMAT); } } if (pStreamProperties->ImageFormat != XN_IMAGE_FORMAT_DISABLED) { if ((pStreamProperties->ImageFormat == XN_IMAGE_FORMAT_RGB24) || (pStreamProperties->ImageFormat == XN_IMAGE_FORMAT_GRAYSCALE8)) { switch (pPackedStreamProperties->StreamImageCompressionFormat) { case XN_COMPRESSED_IMAGE_FORMAT_SKIP: break; case XN_COMPRESSED_IMAGE_FORMAT_UNCOMPRESSED: nBufferSize += pStreamProperties->nImageBufferSize; break; case XN_COMPRESSED_IMAGE_FORMAT_8Z: nBufferSize += (XnUInt32)(pStreamProperties->nImageBufferSize * XN_STREAM_COMPRESSION_IMAGE8Z_WORSE_RATIO); break; case XN_COMPRESSED_IMAGE_FORMAT_JPEG: nBufferSize += (XnUInt32)(pStreamProperties->nImageBufferSize * XN_STREAM_COMPRESSION_IMAGEJ_WORSE_RATIO); break; default: return (XN_STATUS_IO_INVALID_STREAM_IMAGE_COMPRESSION_FORMAT); } } else if (pStreamProperties->ImageFormat == XN_IMAGE_FORMAT_YUV422) { switch (pPackedStreamProperties->StreamImageCompressionFormat) { case XN_COMPRESSED_IMAGE_FORMAT_SKIP: break; case XN_COMPRESSED_IMAGE_FORMAT_UNCOMPRESSED: nBufferSize += pStreamProperties->nImageBufferSize; break; default: return (XN_STATUS_IO_INVALID_STREAM_IMAGE_COMPRESSION_FORMAT); } } else { return (XN_STATUS_IO_INVALID_STREAM_IMAGE_FORMAT); } } if (pStreamProperties->MiscFormat != XN_MISC_FORMAT_DISABLED) { if (pStreamProperties->MiscFormat == XN_MISC_FORMAT_CONFIDENCE_MAP) { switch (pPackedStreamProperties->StreamMiscCompressionFormat) { case XN_COMPRESSED_MISC_FORMAT_SKIP: break; case XN_COMPRESSED_MISC_FORMAT_UNCOMPRESSED: nBufferSize += pStreamProperties->nMiscBufferSize; break; case XN_COMPRESSED_MISC_FORMAT_CONF4: nBufferSize += (XnUInt32)(pStreamProperties->nMiscBufferSize * XN_STREAM_COMPRESSION_CONF4_WORSE_RATIO); break; case XN_COMPRESSED_MISC_FORMAT_CONF4LZ: nBufferSize += (XnUInt32)(pStreamProperties->nMiscBufferSize * XN_STREAM_COMPRESSION_CONF4_WORSE_RATIO); break; default: return (XN_STATUS_IO_INVALID_STREAM_MISC_COMPRESSION_FORMAT); } } else { return (XN_STATUS_IO_INVALID_STREAM_MISC_FORMAT); } } if (pStreamProperties->AudioFormat != XN_AUDIO_FORMAT_DISABLED) { if (pStreamProperties->AudioFormat == XN_AUDIO_FORMAT_PCM) { switch (pPackedStreamProperties->StreamAudioCompressionFormat) { case XN_COMPRESSED_AUDIO_FORMAT_SKIP: break; case XN_COMPRESSED_AUDIO_FORMAT_UNCOMPRESSED: nBufferSize += pStreamProperties->nAudioBufferSize; break; default: return (XN_STATUS_IO_INVALID_STREAM_AUDIO_COMPRESSION_FORMAT); } } else { return (XN_STATUS_IO_INVALID_STREAM_AUDIO_FORMAT); } } nBufferSize += sizeof(XnPackedStreamFrameHeaderV3); return nBufferSize; return (XN_STATUS_OK); } XnStatus XnFileDevice::BCReadInitialState(XnPropertySet* pSet) { // Local function variables XnStatus nRetVal = XN_STATUS_OK; XnDeviceFileHeader DeviceFileHeader; XN_STREAM_FLAGS_TYPE nStreamFlags = 0; m_pBCData->nFramePos = 1; xnOSFreeAligned(m_pBCData->pPackedStreamBuffer); m_pBCData->pPackedStreamBuffer = NULL; m_pBCData->nPackedStreamBufferSize = 0; // read StreamProperties if (m_nFileVersion == 3) { // Current Version nRetVal = m_pInputStream->ReadData((XnUChar*)&DeviceFileHeader.nMajorVersion, sizeof(XnUInt16)); XN_IS_STATUS_OK(nRetVal); nRetVal = m_pInputStream->ReadData((XnUChar*)&DeviceFileHeader.nMinorVersion, sizeof(XnUInt16)); XN_IS_STATUS_OK(nRetVal); nRetVal = m_pInputStream->ReadData((XnUChar*)&DeviceFileHeader.StreamProperties, sizeof(XnStreamPropertiesV3)); XN_IS_STATUS_OK(nRetVal); DeviceFileHeader.nMajorVersion = XN_PREPARE_VAR16_IN_BUFFER(DeviceFileHeader.nMajorVersion); DeviceFileHeader.nMinorVersion = XN_PREPARE_VAR16_IN_BUFFER(DeviceFileHeader.nMinorVersion); nRetVal = XnIOAdjustStreamPropertiesV3(&DeviceFileHeader.StreamProperties, &DeviceFileHeader.StreamProperties); XN_IS_STATUS_OK(nRetVal); } else if (m_nFileVersion == 2) { // Version 2 DeviceFileHeader.nMajorVersion = 0; DeviceFileHeader.nMinorVersion = 0; XnStreamPropertiesV2 StreamPropertiesV2; nRetVal = m_pInputStream->ReadData((XnUChar*)&StreamPropertiesV2, sizeof(XnStreamPropertiesV2)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnIOAdjustStreamPropertiesV2(&StreamPropertiesV2, &DeviceFileHeader.StreamProperties); XN_IS_STATUS_OK(nRetVal); } else if (m_nFileVersion == 1) { // Version 1 DeviceFileHeader.nMajorVersion = 0; DeviceFileHeader.nMinorVersion = 0; XnStreamPropertiesV1 StreamPropertiesV1; nRetVal = m_pInputStream->ReadData((XnUChar*)&StreamPropertiesV1, sizeof(XnStreamPropertiesV1)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnIOAdjustStreamPropertiesV1(&StreamPropertiesV1, &DeviceFileHeader.StreamProperties); XN_IS_STATUS_OK(nRetVal); } else { // Bad Magic return XN_STATUS_IO_INVALID_STREAM_HEADER; } // read packed stream properties switch (m_nFileVersion) { case 3: { nRetVal = m_pInputStream->ReadData((XnUChar*)&DeviceFileHeader.PackedStreamProperties, sizeof(XnPackedStreamProperties)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnIOAdjustPackedStreamPropertiesV3(&DeviceFileHeader.PackedStreamProperties, &DeviceFileHeader.PackedStreamProperties); XN_IS_STATUS_OK(nRetVal); } break; case 2: { XnPackedStreamPropertiesV2 PackedStreamPropertiesV2; nRetVal = m_pInputStream->ReadData((XnUChar*)&PackedStreamPropertiesV2, sizeof(XnPackedStreamPropertiesV2)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnIOAdjustPackedStreamPropertiesV2(&PackedStreamPropertiesV2, &DeviceFileHeader.PackedStreamProperties); XN_IS_STATUS_OK(nRetVal); } break; case 1: { XnPackedStreamPropertiesV1 PackedStreamPropertiesV1; nRetVal = m_pInputStream->ReadData((XnUChar*)&PackedStreamPropertiesV1, sizeof(XnPackedStreamPropertiesV1)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnIOAdjustPackedStreamPropertiesV1(&PackedStreamPropertiesV1, &DeviceFileHeader.PackedStreamProperties); XN_IS_STATUS_OK(nRetVal); } break; default: return XN_STATUS_IO_INVALID_STREAM_HEADER; } // Save the stream properties into the private data (but keep the original stream flags) nStreamFlags = m_pBCData->StreamProperties.nStreamFlags; xnOSMemCopy(&m_pBCData->StreamProperties, &DeviceFileHeader.StreamProperties, sizeof(XnStreamProperties)); m_pBCData->StreamProperties.nStreamFlags = nStreamFlags; if (m_pBCData->StreamProperties.Shift2DepthData.bShift2DepthData) { m_pBCData->StreamProperties.Shift2DepthData.nMaxDepthValue = 10000; m_pBCData->StreamProperties.nDepthMaxValue = 10000; } // Save the packed stream properties into the private data xnOSMemCopy(&m_pBCData->PackedStreamProperties, &DeviceFileHeader.PackedStreamProperties, sizeof(XnPackedStreamProperties)); XnUInt32 nBufferSize = BCCalculatePackedBufferSize(); if (nBufferSize != m_pBCData->nPackedStreamBufferSize) { xnOSFreeAligned(m_pBCData->pPackedStreamBuffer); XN_VALIDATE_ALIGNED_CALLOC(m_pBCData->pPackedStreamBuffer, XnUChar, nBufferSize, XN_DEFAULT_MEM_ALIGN); m_pBCData->nPackedStreamBufferSize = nBufferSize; } nRetVal = ConvertStreamPropertiesToPropertySet(&m_pBCData->StreamProperties, &m_pBCData->PackedStreamProperties, pSet); XN_IS_STATUS_OK(nRetVal); // All is good... return (XN_STATUS_OK); } XnStatus XnFileDevice::BCSeek(XnUInt64 nTimestamp) { return (XN_STATUS_IO_DEVICE_FUNCTION_NOT_SUPPORTED); } XnStatus XnFileDevice::BCSeekFrame(XnUInt32 nFrameID) { XnStatus nRetVal = XN_STATUS_OK; XnDeviceFileFrameHeaderV3 FileFrameHeader; XnUInt32 nReadBytes = 0; XnUInt32 nShouldRead = 0; XnInt32 nExpectedFrameID = 1; // go back to start of file nRetVal = Rewind(); XN_IS_STATUS_OK(nRetVal); // Update the frame position to the new position (treat 0 as 1) m_pBCData->nFramePos = XN_MAX(nFrameID, 1); // Make sure we aren't trying to reach a frame that's beyond the number of frames if (m_pBCData->nFramePos > m_pBCData->StreamProperties.nNumOfFrames) { // Set the frame position to the last frame m_pBCData->nFramePos = m_pBCData->StreamProperties.nNumOfFrames; } // Set the file position to the first frame data (right after the file header) XnUInt32 nOffset = 0; switch (m_nFileVersion) { case 3: nOffset = sizeof(XnDeviceFileHeader); break; case 2: nOffset = sizeof(XnDeviceFileHeaderV2); break; case 1: nOffset = sizeof(XnDeviceFileHeaderV1); break; default: return (XN_STATUS_IO_INVALID_STREAM_HEADER); } nRetVal = m_pInputStream->Seek(nOffset); XN_IS_STATUS_OK(nRetVal); // Keep reading frames until we reach the wanted frame XnUInt32 nCurrFilePos = 1; while (nCurrFilePos < m_pBCData->nFramePos) { // Read the frame header switch (m_nFileVersion) { case 3: { nShouldRead = nReadBytes = sizeof(XnDeviceFileFrameHeaderV3); nRetVal = m_pInputStream->ReadData((XnUChar*)&FileFrameHeader, nReadBytes); XN_IS_STATUS_OK(nRetVal); nExpectedFrameID = nCurrFilePos; } break; case 2: { XnDeviceFileFrameHeaderV2 FileFrameHeaderV2; nShouldRead = nReadBytes = sizeof(XnDeviceFileFrameHeaderV2); nRetVal = m_pInputStream->ReadData((XnUChar*)&FileFrameHeaderV2, nReadBytes); XN_IS_STATUS_OK(nRetVal); nRetVal = XnDeviceFileAdjustFileFrameHeaderV2(&FileFrameHeaderV2, &FileFrameHeader); XN_IS_STATUS_OK(nRetVal); nExpectedFrameID = nCurrFilePos - 1; } break; case 1: { XnDeviceFileFrameHeaderV1 FileFrameHeaderV1; nShouldRead = nReadBytes = sizeof(XnDeviceFileFrameHeaderV1); nRetVal = m_pInputStream->ReadData((XnUChar*)&FileFrameHeaderV1, nReadBytes); XN_IS_STATUS_OK(nRetVal); nRetVal = XnDeviceFileAdjustFileFrameHeaderV1(&FileFrameHeaderV1, &FileFrameHeader); XN_IS_STATUS_OK(nRetVal); nExpectedFrameID = nCurrFilePos - 1; } break; default: return XN_STATUS_IO_INVALID_STREAM_HEADER; } // Make sure we got the right header size if (nReadBytes != nShouldRead) { return (XN_STATUS_IO_INVALID_STREAM_FRAME_HEADER); } // Skip the frame data XnUInt32 nPosition; nRetVal = m_pInputStream->Tell(&nPosition); XN_IS_STATUS_OK(nRetVal); nRetVal = m_pInputStream->Seek(FileFrameHeader.nPackedStreamSize + nPosition); XN_IS_STATUS_OK(nRetVal); // increment streams frame ID for (XnNodeInfoMap::Iterator it = m_nodeInfoMap.begin(); it != m_nodeInfoMap.end(); ++it) { it.Value().nCurrFrameID++; } // Make sure frame ids are sequential if (FileFrameHeader.FrameProperties.nDepthFrameID != nExpectedFrameID) { return (XN_STATUS_IO_STREAM_NOT_SEQUENTIAL); } // Update the current file frame position nCurrFilePos++; } // now read last frame (the one we wanted) XnBool bWrapOccured; nRetVal = BCReadFrame(&bWrapOccured); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); } XnStatus XnFileDevice::BCReadFrame(XnBool* pbWrapOccured) { // Local function variables XnStatus nRetVal = XN_STATUS_OK; XnDeviceFileFrameHeaderV3 FileFrameHeader; XnUInt64 nCurrTime = 0; XnUInt64 nDiffTime = 0; XnUInt64 nFramesDiffTime = 0; XnUInt32 nSleepTime = 0; *pbWrapOccured = FALSE; // If we've reached the last frame, seek back to the first one if (m_pBCData->nFramePos > m_pBCData->StreamProperties.nNumOfFrames) { nRetVal = HandleEndOfStream(); XN_IS_STATUS_OK(nRetVal); *pbWrapOccured = TRUE; if (m_bEOF) { return XN_STATUS_OK; } } m_bFileHasData = TRUE; // Note: Since this is an internal function, the pointers are assumed to be checked by the caller // Read the frame header switch (m_nFileVersion) { case 3: { nRetVal = m_pInputStream->ReadData((XnUChar*)&FileFrameHeader, sizeof(XnDeviceFileFrameHeaderV3)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnDeviceFileAdjustFileFrameHeaderV3(&FileFrameHeader, &FileFrameHeader); XN_IS_STATUS_OK(nRetVal); } break; case 2: { XnDeviceFileFrameHeaderV2 FileFrameHeaderV2; nRetVal = m_pInputStream->ReadData((XnUChar*)&FileFrameHeaderV2, sizeof(XnDeviceFileFrameHeaderV2)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnDeviceFileAdjustFileFrameHeaderV2(&FileFrameHeaderV2, &FileFrameHeader); XN_IS_STATUS_OK(nRetVal); } break; case 1: { XnDeviceFileFrameHeaderV1 FileFrameHeaderV1; nRetVal = m_pInputStream->ReadData((XnUChar*)&FileFrameHeaderV1, sizeof(XnDeviceFileFrameHeaderV1)); XN_IS_STATUS_OK(nRetVal); nRetVal = XnDeviceFileAdjustFileFrameHeaderV1(&FileFrameHeaderV1, &FileFrameHeader); XN_IS_STATUS_OK(nRetVal); } break; default: return XN_STATUS_IO_INVALID_STREAM_HEADER; } FileFrameHeader.FrameProperties.nDepthFrameID = m_pBCData->nFramePos; FileFrameHeader.FrameProperties.nImageFrameID = m_pBCData->nFramePos; // Make sure we aren't going to overflow the packed stream buffer if (FileFrameHeader.nPackedStreamSize > m_pBCData->nPackedStreamBufferSize) { return (XN_STATUS_INPUT_BUFFER_OVERFLOW); } // Read the frame packed stream data into the packed stream buffer nRetVal = m_pInputStream->ReadData(m_pBCData->pPackedStreamBuffer, FileFrameHeader.nPackedStreamSize); XN_IS_STATUS_OK(nRetVal); // read the frame header XnPackedStreamFrameHeaderV3 PackedStreamHeader; XnUChar* pPackedBuffer = m_pBCData->pPackedStreamBuffer; switch (m_nFileVersion) { case 0: case 3: { xnOSMemCopy(&PackedStreamHeader, pPackedBuffer, sizeof(XnPackedStreamFrameHeaderV3)); pPackedBuffer += sizeof(XnPackedStreamFrameHeaderV3); nRetVal = XnIOAdjustPackedStreamFrameHeaderV3(&PackedStreamHeader, &PackedStreamHeader); XN_IS_STATUS_OK(nRetVal); break; } case 2: { XnPackedStreamFrameHeaderV2* pPackedStreamHeaderV2 = (XnPackedStreamFrameHeaderV2*)pPackedBuffer; pPackedBuffer += sizeof(XnPackedStreamFrameHeaderV2); nRetVal = XnIOAdjustPackedStreamFrameHeaderV2(pPackedStreamHeaderV2, &PackedStreamHeader); XN_IS_STATUS_OK(nRetVal); break; } case 1: { XnPackedStreamFrameHeaderV1* pPackedStreamHeaderV1 = (XnPackedStreamFrameHeaderV1*)pPackedBuffer; pPackedBuffer += sizeof(XnPackedStreamFrameHeaderV1); nRetVal = XnIOAdjustPackedStreamFrameHeaderV1(pPackedStreamHeaderV1, &PackedStreamHeader); XN_IS_STATUS_OK(nRetVal); break; } default: return XN_STATUS_IO_INVALID_STREAM_HEADER; } // Depth XnNodeInfo* pNodeInfo; if (XN_STATUS_OK == m_nodeInfoMap.Get(XN_STREAM_NAME_DEPTH, pNodeInfo)) { m_pStreamData->nDataSize = m_pBCData->StreamProperties.nDepthBufferSize; nRetVal = pNodeInfo->pXnCodec->Decompress(pPackedBuffer, PackedStreamHeader.nCompDepthBufferSize, (XnUChar*)m_pStreamData->pData, &m_pStreamData->nDataSize); XN_IS_STATUS_OK(nRetVal); nRetVal = m_pNotifications->OnNodeNewData(m_pNotificationsCookie, XN_STREAM_NAME_DEPTH, FileFrameHeader.FrameProperties.nDepthTimeStamp * 1000, m_pBCData->nFramePos, m_pStreamData->pData, m_pBCData->StreamProperties.nDepthBufferSize); XN_IS_STATUS_OK(nRetVal); pNodeInfo->nCurrFrameID++; pPackedBuffer += PackedStreamHeader.nCompDepthBufferSize; } // Image if (XN_STATUS_OK == m_nodeInfoMap.Get(XN_STREAM_NAME_IMAGE, pNodeInfo)) { m_pStreamData->nDataSize = m_pBCData->StreamProperties.nImageBufferSize; nRetVal = pNodeInfo->pXnCodec->Decompress(pPackedBuffer, PackedStreamHeader.nCompImageBufferSize, (XnUChar*)m_pStreamData->pData, &m_pStreamData->nDataSize); XN_IS_STATUS_OK(nRetVal); nRetVal = m_pNotifications->OnNodeNewData(m_pNotificationsCookie, XN_STREAM_NAME_IMAGE, FileFrameHeader.FrameProperties.nImageTimeStamp * 1000, m_pBCData->nFramePos, m_pStreamData->pData, m_pBCData->StreamProperties.nImageBufferSize); XN_IS_STATUS_OK(nRetVal); pNodeInfo->nCurrFrameID++; pPackedBuffer += PackedStreamHeader.nCompImageBufferSize; } // we do not support MISC pPackedBuffer += PackedStreamHeader.nCompMiscBufferSize; // Audio if (XN_STATUS_OK == m_nodeInfoMap.Get(XN_STREAM_NAME_AUDIO, pNodeInfo)) { m_pStreamData->nDataSize = m_pBCData->StreamProperties.nAudioBufferSize; nRetVal = pNodeInfo->pXnCodec->Decompress(pPackedBuffer, PackedStreamHeader.nCompAudioBufferSize, (XnUChar*)m_pStreamData->pData, &m_pStreamData->nDataSize); XN_IS_STATUS_OK(nRetVal); nRetVal = m_pNotifications->OnNodeNewData(m_pNotificationsCookie, XN_STREAM_NAME_AUDIO, FileFrameHeader.FrameProperties.nAudioTimeStamp * 1000, m_pBCData->nFramePos, m_pStreamData->pData, m_pStreamData->nDataSize); XN_IS_STATUS_OK(nRetVal); pNodeInfo->nCurrFrameID++; pPackedBuffer += PackedStreamHeader.nCompAudioBufferSize; } // Increase the file frame position m_pBCData->nFramePos++; // All is good... return (XN_STATUS_OK); } XnStatus XnFileDevice::BCDestroy() { if (m_pBCData != NULL) { xnOSFreeAligned(m_pBCData->pPackedStreamBuffer); xnOSFree(m_pBCData); } return XN_STATUS_OK; }