示例#1
1
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;
}
示例#2
0
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;
}
示例#3
0
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;	
}
示例#4
0
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;
}
示例#5
0
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);
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;	
}
示例#9
0
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;	
}
示例#10
0
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);
}
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
0
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;
}