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::RemovePlayerNodeInfo(XnUInt32 nNodeID) { XnStatus nRetVal = XN_STATUS_OK; xn::Player playerNode; nRetVal = m_context.GetProductionNodeByName(m_strName, playerNode); XN_IS_STATUS_OK(nRetVal); PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(nNodeID); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (pPlayerNodeInfo->bValid) { if (m_pNodeNotifications != NULL) { nRetVal = m_pNodeNotifications->OnNodeRemoved(m_pNotificationsCookie, pPlayerNodeInfo->strName); if (nRetVal != XN_STATUS_OK) { return nRetVal; } } playerNode.RemoveNeededNode(pPlayerNodeInfo->codec); pPlayerNodeInfo->codec = NULL; pPlayerNodeInfo->Reset(); //Now it's not valid anymore } return XN_STATUS_OK; }
XnStatus PlayerNode::RemovePlayerNodeInfo(XnUInt32 nNodeID) { XnStatus nRetVal = XN_STATUS_OK; PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(nNodeID); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); if (pPlayerNodeInfo->bValid) { if (m_pNodeNotifications != NULL) { nRetVal = m_pNodeNotifications->OnNodeRemoved(m_pNotificationsCookie, pPlayerNodeInfo->strName); if (nRetVal != XN_STATUS_OK) { return nRetVal; } } if (pPlayerNodeInfo->codec.IsValid()) { xnRemoveNeededNode(GetSelfNodeHandle(), pPlayerNodeInfo->codec); pPlayerNodeInfo->codec.Release(); } pPlayerNodeInfo->Reset(); //Now it's not valid anymore } 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::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::HandleNodeAddedImpl(XnUInt32 nNodeID, XnProductionNodeType type, const XnChar* strName, XnCodecID compression, XnUInt32 nNumberOfFrames, XnUInt64 nMinTimestamp, XnUInt64 nMaxTimestamp) { XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnStatus nRetVal = XN_STATUS_OK; PlayerNodeInfo* pPlayerNodeInfo = GetPlayerNodeInfo(nNodeID); XN_VALIDATE_PTR(pPlayerNodeInfo, XN_STATUS_CORRUPT_FILE); //Notify node was added nRetVal = m_pNodeNotifications->OnNodeAdded(m_pNotificationsCookie, strName, type, compression); XN_IS_STATUS_OK(nRetVal); pPlayerNodeInfo->compression = compression; nRetVal = xnOSStrCopy(pPlayerNodeInfo->strName, strName, sizeof(pPlayerNodeInfo->strName)); XN_IS_STATUS_OK(nRetVal); if (xnIsTypeGenerator(type)) { pPlayerNodeInfo->bIsGenerator = TRUE; pPlayerNodeInfo->nFrames = nNumberOfFrames; pPlayerNodeInfo->nMaxTimeStamp = nMaxTimestamp; } //Mark this player node as valid pPlayerNodeInfo->bValid = TRUE; //Loop until this node's state is ready. //TODO: Check for eof while (!pPlayerNodeInfo->bStateReady) { nRetVal = ProcessRecord(TRUE); if (nRetVal != XN_STATUS_OK) { pPlayerNodeInfo->bValid = FALSE; return nRetVal; } } 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::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::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; }