XnStatus PlayerNode::HandleDataIndexRecord(DataIndexRecordHeader record, XnBool bReadPayload) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "DataIndex"); XN_ASSERT(record.GetNodeID() != INVALID_NODE_ID); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); XnUInt32 nRecordTotalSize = record.GetSize() + record.GetPayloadSize(); if (nRecordTotalSize > RECORD_MAX_SIZE) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_INTERNAL_BUFFER_TOO_SMALL, XN_MASK_OPEN_NI, "Record size %u is larger than player internal buffer", nRecordTotalSize); } if (bReadPayload) { // make sure node exists if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } if (record.GetPayloadSize() != (pPlayerNodeInfo->nFrames+1) * sizeof(DataIndexEntry)) { XN_ASSERT(FALSE); XN_LOG_WARNING_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Seek table has %u entries, but node has %u frames!", record.GetPayloadSize() / sizeof(DataIndexEntry), pPlayerNodeInfo->nFrames); } // allocate our data index pPlayerNodeInfo->pDataIndex = (DataIndexEntry*)xnOSCalloc(pPlayerNodeInfo->nFrames+1, sizeof(DataIndexEntry)); XN_VALIDATE_ALLOC_PTR(pPlayerNodeInfo->pDataIndex); //Now read the actual data XnUInt32 nBytesRead = 0; nRetVal = Read(pPlayerNodeInfo->pDataIndex, record.GetPayloadSize(), nBytesRead); XN_IS_STATUS_OK(nRetVal); if (nBytesRead < record.GetPayloadSize()) { XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Not enough bytes read"); } } else { //Just skip the data nRetVal = SkipRecordPayload(record); XN_IS_STATUS_OK(nRetVal); } return XN_STATUS_OK; }
XnStatus PlayerNode::HandleStringPropRecord(StringPropRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "StringProp"); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } nRetVal = m_pNodeNotifications->OnNodeStringPropChanged(m_pNotificationsCookie, pPlayerNodeInfo->strName, record.GetPropName(), record.GetValue()); XN_IS_STATUS_OK(nRetVal); nRetVal = SaveRecordUndoInfo(pPlayerNodeInfo, record.GetPropName(), TellStream() - record.GetSize(), record.GetUndoRecordPos()); XN_IS_STATUS_OK(nRetVal); return XN_STATUS_OK; }
XnStatus PlayerNode::HandleEndRecord(EndRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "End"); if (!m_bDataBegun) { XN_LOG_WARNING_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "File does not contain any data!"); } nRetVal = m_eofReachedEvent.Raise(); XN_IS_STATUS_OK(nRetVal); if (m_bRepeat) { nRetVal = Rewind(); XN_IS_STATUS_OK(nRetVal); } else { m_bEOF = TRUE; CloseStream(); } return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNodeStateReadyRecord(NodeStateReadyRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeStateReady"); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } nRetVal = m_pNodeNotifications->OnNodeStateReady(m_pNotificationsCookie, pPlayerNodeInfo->strName); XN_IS_STATUS_OK(nRetVal); if (pPlayerNodeInfo->bIsGenerator && (pPlayerNodeInfo->compression != XN_CODEC_NULL) && !pPlayerNodeInfo->codec.IsValid()) { xn::ProductionNode node; /*at this point the node should have all its properties set so we can create the codec. A node with the name pPlayerNodeInfo->strName should have been created by now. If it wasn't, GetProductionNodeByName() will fail. */ nRetVal = m_context.GetProductionNodeByName(pPlayerNodeInfo->strName, node); XN_IS_STATUS_OK(nRetVal); nRetVal = m_context.CreateCodec(pPlayerNodeInfo->compression, node, pPlayerNodeInfo->codec); XN_IS_STATUS_OK(nRetVal); // make the player dependent on the codec xn::Player playerNode; nRetVal = m_context.GetProductionNodeByName(m_strName, playerNode); if (nRetVal != XN_STATUS_OK) { pPlayerNodeInfo->codec.Unref(); return (nRetVal); } nRetVal = playerNode.AddNeededNode(pPlayerNodeInfo->codec); if (nRetVal != XN_STATUS_OK) { pPlayerNodeInfo->codec.Unref(); return (nRetVal); } // at this point, we can unref the codec (it will still have at least one ref, as we added it to needed nodes). xn::Codec codec = pPlayerNodeInfo->codec; codec.Unref(); } pPlayerNodeInfo->bStateReady = TRUE; return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNodeAddedRecord(NodeAddedRecord record) { XnStatus nRetVal = XN_STATUS_OK; nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeAdded"); nRetVal = HandleNodeAddedImpl( record.GetNodeID(), record.GetNodeType(), record.GetNodeName(), record.GetCompression(), record.GetNumberOfFrames(), record.GetMinTimestamp(), record.GetMaxTimestamp()); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }
XnStatus PlayerNode::HandleNodeStateReadyRecord(NodeStateReadyRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeStateReady"); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } // after wrap-around, if node wasn't destroyed, no need to notify about state ready if (!pPlayerNodeInfo->bStateReady) { nRetVal = m_pNodeNotifications->OnNodeStateReady(m_pNotificationsCookie, pPlayerNodeInfo->strName); XN_IS_STATUS_OK(nRetVal); } if (pPlayerNodeInfo->bIsGenerator && (pPlayerNodeInfo->compression != XN_CODEC_NULL) && !pPlayerNodeInfo->codec.IsValid()) { xn::ProductionNode node; /*at this point the node should have all its properties set so we can create the codec. A node with the name pPlayerNodeInfo->strName should have been created by now. If it wasn't, GetProductionNodeByName() will fail. */ nRetVal = m_context.GetProductionNodeByName(pPlayerNodeInfo->strName, node); XN_IS_STATUS_OK(nRetVal); nRetVal = m_context.CreateCodec(pPlayerNodeInfo->compression, node, pPlayerNodeInfo->codec); XN_IS_STATUS_OK(nRetVal); // we need to make the codec a needed node, so that if xnForceShutdown() is called, we will be // destroyed *before* it does (as we hold a reference to it). nRetVal = xnAddNeededNode(GetSelfNodeHandle(), pPlayerNodeInfo->codec); XN_IS_STATUS_OK(nRetVal); } pPlayerNodeInfo->bStateReady = TRUE; return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNodeRemovedRecord(NodeRemovedRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeRemoved"); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Got a node removed record for non-existing node %u.", record.GetNodeID()); } nRetVal = RemovePlayerNodeInfo(record.GetNodeID()); XN_IS_STATUS_OK(nRetVal); return XN_STATUS_OK; }
XnStatus PlayerNode::HandleEndRecord(EndRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "End"); nRetVal = m_eofReachedEvent.Raise(); XN_IS_STATUS_OK(nRetVal); if (m_bRepeat) { nRetVal = Rewind(); XN_IS_STATUS_OK(nRetVal); } else { m_bEOF = TRUE; CloseStream(); } return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNodeDataBeginRecord(NodeDataBeginRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeDataBegin"); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } if (!pPlayerNodeInfo->bIsGenerator) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Got data for non-generator node '%s'", pPlayerNodeInfo->strName); } m_bDataBegun = TRUE; return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNodeAddedRecord(NodeAddedRecord record) { XnStatus nRetVal = XN_STATUS_OK; nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeAdded"); nRetVal = HandleNodeAddedImpl( record.GetNodeID(), record.GetNodeType(), record.GetNodeName(), record.GetCompression(), record.GetNumberOfFrames(), record.GetMinTimestamp(), record.GetMaxTimestamp()); XN_IS_STATUS_OK(nRetVal); // get seek table (if exists) if (record.GetNumberOfFrames() > 0 && record.GetSeekTablePosition() != 0) { XnUInt32 nCurrPos = TellStream(); nRetVal = SeekStream(XN_OS_SEEK_SET, record.GetSeekTablePosition()); XN_IS_STATUS_OK(nRetVal); DataIndexRecordHeader seekTableHeader(m_pRecordBuffer, RECORD_MAX_SIZE); nRetVal = ReadRecord(seekTableHeader); XN_IS_STATUS_OK(nRetVal); nRetVal = HandleDataIndexRecord(seekTableHeader, TRUE); XN_IS_STATUS_OK(nRetVal); // and seek back nRetVal = SeekStream(XN_OS_SEEK_SET, nCurrPos); XN_IS_STATUS_OK(nRetVal); } return (XN_STATUS_OK); }
XnStatus PlayerNode::HandleGeneralPropRecord(GeneralPropRecord record) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "GeneralProp"); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } // Fix backwards compatibility issues if (strcmp(record.GetPropName(), XN_PROP_REAL_WORLD_TRANSLATION_DATA) == 0) { // old recordings held the RealWorldTranslationData, but API has changed. Translate // it to Field Of View if (record.GetPropDataSize() != sizeof(XnRealWorldTranslationData)) { return XN_STATUS_CORRUPT_FILE; } const XnRealWorldTranslationData* pTransData = (const XnRealWorldTranslationData*)record.GetPropData(); // we also need resolution for the translation xn::DepthGenerator depthGen; nRetVal = m_context.GetProductionNodeByName(pPlayerNodeInfo->strName, depthGen); XN_IS_STATUS_OK(nRetVal); XnMapOutputMode outputMode; nRetVal = depthGen.GetMapOutputMode(outputMode); XN_IS_STATUS_OK(nRetVal); XnFieldOfView FOV; FOV.fHFOV = 2*atan(pTransData->dPixelSizeAtZeroPlane * pTransData->dSourceToDepthPixelRatio * outputMode.nXRes / 2 / pTransData->dZeroPlaneDistance); FOV.fVFOV = 2*atan(pTransData->dPixelSizeAtZeroPlane * pTransData->dSourceToDepthPixelRatio * outputMode.nYRes / 2 / pTransData->dZeroPlaneDistance); nRetVal = m_pNodeNotifications->OnNodeGeneralPropChanged(m_pNotificationsCookie, pPlayerNodeInfo->strName, XN_PROP_FIELD_OF_VIEW, sizeof(FOV), &FOV); XN_IS_STATUS_OK(nRetVal); } else { nRetVal = m_pNodeNotifications->OnNodeGeneralPropChanged(m_pNotificationsCookie, pPlayerNodeInfo->strName, record.GetPropName(), record.GetPropDataSize(), record.GetPropData()); XN_IS_STATUS_OK(nRetVal); } nRetVal = SaveRecordUndoInfo(pPlayerNodeInfo, record.GetPropName(), TellStream() - record.GetSize(), record.GetUndoRecordPos()); XN_IS_STATUS_OK(nRetVal); return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNodeAdded_1_0_0_4_Record(NodeAdded_1_0_0_4_Record record) { XnStatus nRetVal = XN_STATUS_OK; nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NodeAdded1_0_0_4"); /** BC issue **/ // NOTE: ONI files up to version 1.0.0.4 didn't had a different NodeAdded record. It did // not contain seek data (number of frames and min/max timestamp). Instead, this data was // in the DataBegin record. So we need to also find this record, and read these props from it. XnUInt32 nNodeID = record.GetNodeID(); XnChar strName[XN_MAX_NAME_LENGTH]; nRetVal = xnOSStrCopy(strName, record.GetNodeName(), XN_MAX_NAME_LENGTH); XN_IS_STATUS_OK(nRetVal); XnProductionNodeType type = record.GetNodeType(); XnCodecID compression = record.GetCompression(); XnUInt32 nNumFrames = 0; XnUInt64 nMinTimestamp = 0; XnUInt64 nMaxTimestamp = 0; if (xnIsTypeGenerator(type)) { // we need to look for the DataBegin record to have number of frames, etc. XnUInt32 nStartPos = TellStream(); // NOTE: this overwrites the current NodeAdded record buffer!!! nRetVal = SeekToRecordByType(nNodeID, RECORD_NODE_DATA_BEGIN); if (nRetVal == XN_STATUS_OK) { NodeDataBeginRecord dataBeginRecord(m_pRecordBuffer, RECORD_MAX_SIZE); nRetVal = ReadRecord(dataBeginRecord); XN_IS_STATUS_OK(nRetVal); nRetVal = dataBeginRecord.Decode(); XN_IS_STATUS_OK(nRetVal); nNumFrames = dataBeginRecord.GetNumFrames(); nMaxTimestamp = dataBeginRecord.GetMaxTimeStamp(); // also find data record for min timestamp nRetVal = SeekToRecordByType(record.GetNodeID(), RECORD_NEW_DATA); if (nRetVal == XN_STATUS_OK) { NewDataRecordHeader newDataRecord(m_pRecordBuffer, RECORD_MAX_SIZE); nRetVal = ReadRecord(newDataRecord); XN_IS_STATUS_OK(nRetVal); nRetVal = newDataRecord.Decode(); XN_IS_STATUS_OK(nRetVal); nMinTimestamp = newDataRecord.GetTimeStamp(); } // get back to start position nRetVal = SeekStream(XN_OS_SEEK_SET, nStartPos); XN_IS_STATUS_OK(nRetVal); } } nRetVal = HandleNodeAddedImpl(nNodeID, type, strName, compression, nNumFrames, nMinTimestamp, nMaxTimestamp); XN_IS_STATUS_OK(nRetVal); return XN_STATUS_OK; }
XnStatus PlayerNode::HandleNewDataRecord(NewDataRecordHeader record, XnBool bReadPayload) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); DEBUG_LOG_RECORD(record, "NewData"); XN_ASSERT(record.GetNodeID() != INVALID_NODE_ID); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(record.GetNodeID()); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (!pPlayerNodeInfo->bValid) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } XnUInt32 nRecordTotalSize = record.GetSize() + record.GetPayloadSize(); if (nRecordTotalSize > RECORD_MAX_SIZE) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_INTERNAL_BUFFER_TOO_SMALL, XN_MASK_OPEN_NI, "Record size %u is larger than player internal buffer", nRecordTotalSize); } pPlayerNodeInfo->nLastDataPos = TellStream() - record.GetSize(); pPlayerNodeInfo->newDataUndoInfo.nRecordPos = pPlayerNodeInfo->nLastDataPos; pPlayerNodeInfo->newDataUndoInfo.nUndoRecordPos = record.GetUndoRecordPos(); if (record.GetFrameNumber() > pPlayerNodeInfo->nFrames) { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } pPlayerNodeInfo->nCurFrame = record.GetFrameNumber(); if (record.GetTimeStamp() > m_nGlobalMaxTimeStamp) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Record timestamp for record in position %u is larger than reported max timestamp", pPlayerNodeInfo->nLastDataPos); } m_nTimeStamp = record.GetTimeStamp(); if (bReadPayload) { //Now read the actual data XnUInt32 nBytesRead = 0; nRetVal = Read(record.GetPayload(), record.GetPayloadSize(), nBytesRead); XN_IS_STATUS_OK(nRetVal); if (nBytesRead < record.GetPayloadSize()) { XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Not enough bytes read"); } const XnUInt8* pCompressedData = record.GetPayload(); //The new (compressed) data is right at the end of the header XnUInt32 nCompressedDataSize = record.GetPayloadSize(); const XnUInt8* pUncompressedData = NULL; XnUInt32 nUncompressedDataSize = 0; XnCodecID compression = pPlayerNodeInfo->codec.GetCodecID(); if (compression == XN_CODEC_UNCOMPRESSED) { pUncompressedData = pCompressedData; nUncompressedDataSize = nCompressedDataSize; } else { //Decode data with codec nRetVal = pPlayerNodeInfo->codec.DecodeData(pCompressedData, nCompressedDataSize, m_pUncompressedData, DATA_MAX_SIZE, &nUncompressedDataSize); XN_IS_STATUS_OK(nRetVal); pUncompressedData = m_pUncompressedData; } nRetVal = m_pNodeNotifications->OnNodeNewData(m_pNotificationsCookie, pPlayerNodeInfo->strName, record.GetTimeStamp(), record.GetFrameNumber(), pUncompressedData, nUncompressedDataSize); XN_IS_STATUS_OK(nRetVal); } else { //Just skip the data nRetVal = SkipRecordPayload(record); XN_IS_STATUS_OK(nRetVal); } return XN_STATUS_OK; }