XnStatus PlayerNode::UndoRecord(PlayerNode::RecordUndoInfo& undoInfo, XnUInt32 nDestPos, XnBool& bUndone) { XnStatus nRetVal = XN_STATUS_OK; XnUInt32 nOriginalPos = TellStream(); bUndone = FALSE; Record record(m_pRecordBuffer, RECORD_MAX_SIZE); while ((undoInfo.nRecordPos > nDestPos) && (undoInfo.nUndoRecordPos != 0)) { nRetVal = SeekStream(XN_OS_SEEK_SET, undoInfo.nUndoRecordPos); XN_IS_STATUS_OK(nRetVal); nRetVal = ReadRecordHeader(record); XN_IS_STATUS_OK(nRetVal); undoInfo.nRecordPos = undoInfo.nUndoRecordPos; undoInfo.nUndoRecordPos = record.GetUndoRecordPos(); } if (undoInfo.nRecordPos <= nDestPos) { /*We found a record that can undo the record originally pointed to by undoInfo.nDestRecordPos, so now we handle it. */ nRetVal = ReadRecordFields(record); XN_IS_STATUS_OK(nRetVal); nRetVal = HandleRecord(record, FALSE); XN_IS_STATUS_OK(nRetVal); bUndone = TRUE; } else { nRetVal = SeekStream(XN_OS_SEEK_SET, nOriginalPos); XN_IS_STATUS_OK(nRetVal); } return XN_STATUS_OK; }
int FSearch( unsigned handle, char *str, char *buff_start, unsigned buff_size, unsigned prefix_len ) { unsigned long size; unsigned long offset; unsigned long match_pos; unsigned str_len; status stat; buffer buff; buff.size = buff_size; buff.start = buff_start; str_len = strlen( str ); match_pos = -1; offset = 0; for( size = SeekStream( handle, 0L, DIO_SEEK_END ) >> 1; size > 0; size >>= 1 ) { FilePos = offset + size; SeekStream( handle, FilePos, DIO_SEEK_ORG ); buff.end = buff.start; buff.ptr = buff.end; stat = FindTag( handle, &buff, str, str_len, prefix_len ); if( stat == EXACT ) { match_pos = FilePos; break; /* from for loop */ } else if( stat == MATCH ) { match_pos = FilePos; } else if( stat == LOW ) { offset += size; } } if( match_pos == -1 ) return( 0 ); SeekStream( handle, match_pos, DIO_SEEK_ORG ); return( 1 ); }
HELPIO long int HelpFileLen( HelpFp fp ) { unsigned long old; long len; old = SeekStream( (file_handle)fp, 0, DIO_SEEK_CUR ); len = SeekStream( (file_handle)fp, 0, DIO_SEEK_END ); SeekStream( (file_handle)fp, old, DIO_SEEK_ORG ); return( len ); }
XnStatus PlayerNode::SeekToRecordByType(XnUInt32 nNodeID, RecordType type) { XnStatus nRetVal = XN_STATUS_OK; Record record(m_pRecordBuffer, RECORD_MAX_SIZE); XnUInt32 nStartPos = TellStream(); XnBool bFound = FALSE; XnUInt32 nPosBeforeRecord = 0; while (!bFound && nRetVal == XN_STATUS_OK) { nPosBeforeRecord = TellStream(); nRetVal = ReadRecord(record); XN_IS_STATUS_OK(nRetVal); if ((record.GetType() == type) && (record.GetNodeID() == nNodeID)) { bFound = TRUE; } else if (record.GetType() == RECORD_END) { nRetVal = XN_STATUS_NO_MATCH; } else { // if record has payload, skip it nRetVal = SkipRecordPayload(record); } } if (bFound) { // seek to before requested record nRetVal = SeekStream(XN_OS_SEEK_SET, nPosBeforeRecord); XN_IS_STATUS_OK(nRetVal); } else { // seek back to starting position SeekStream(XN_OS_SEEK_SET, nStartPos); return (nRetVal); } return (XN_STATUS_OK); }
void PLRSeek (MUSIC_REF MusicRef, DWORD pos) { if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0) { LockMutex (soundSource[MUSIC_SOURCE].stream_mutex); SeekStream (MUSIC_SOURCE, pos); UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex); } }
XnStatus PlayerNode::ProcessEachNodeLastData(XnUInt32 nIDToProcessLast) { XnStatus nRetVal = XN_STATUS_OK; XnUInt32 nItNodeID = 0; //Node ID handled in each iteration. for (XnUInt32 i = 0; i < m_nMaxNodes; i++) { /*We switch positions between nIDToProcessLast and the last position, to make sure that nIDToProcessLast is handled last. This way the position at the end of our seek operation is right after the record we read for nIDToProcessLast.*/ if (i == nIDToProcessLast) { nItNodeID = m_nMaxNodes - 1; } else if (i == m_nMaxNodes - 1) { nItNodeID = nIDToProcessLast; } else { nItNodeID = i; } PlayerNodeInfo &pni = m_pNodeInfoMap[nItNodeID]; if (pni.bIsGenerator) { if (!pni.bValid) { xnLogError(XN_MASK_OPEN_NI, "Node with ID %u is not valid", nItNodeID); XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } if (pni.nLastDataPos == 0) { /*This means we had to undo this node's data, but found no data frame before our main node's data frame. In this case we push a 0 frame.*/ memset(m_pRecordBuffer, 0, RECORD_MAX_SIZE); nRetVal = m_pNodeNotifications->OnNodeNewData(m_pNotificationsCookie, pni.strName, 0, 0, m_pRecordBuffer, RECORD_MAX_SIZE); XN_IS_STATUS_OK(nRetVal); } else { nRetVal = SeekStream(XN_OS_SEEK_SET, pni.nLastDataPos); XN_IS_STATUS_OK(nRetVal); nRetVal = ProcessRecord(TRUE); XN_IS_STATUS_OK(nRetVal); } } } //Now our position is right after the last data of the node with id nIDToProcessLast 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::Rewind() { //skip recording header XnStatus nRetVal = SeekStream(XN_OS_SEEK_SET, sizeof(RecordingHeader)); XN_IS_STATUS_OK(nRetVal); //Reset all node info's for (XnUInt32 i = 0; i < m_nMaxNodes; i++) { m_pNodeInfoMap[i].Reset(); } m_bDataBegun = FALSE; m_nTimeStamp = 0; m_bEOF = FALSE; //Skip to first data nRetVal = ProcessUntilFirstData(); 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::SeekToFrameAbsolute(XnUInt32 nNodeID, XnUInt32 nDestFrame) { XN_ASSERT((nNodeID != INVALID_NODE_ID) && (nNodeID < m_nMaxNodes)); PlayerNodeInfo* pPlayerNodeInfo = &m_pNodeInfoMap[nNodeID]; XN_ASSERT((nDestFrame > 0) && (nDestFrame <= pPlayerNodeInfo->nFrames)); XN_VALIDATE_INPUT_PTR(m_pNodeNotifications); XnUInt32 nStartPos = TellStream(); XnUInt32 nNextFrame = pPlayerNodeInfo->nCurFrame + 1; XnUInt32 nFrames = pPlayerNodeInfo->nFrames; XnStatus nRetVal = XN_STATUS_OK; if (nDestFrame == pPlayerNodeInfo->nCurFrame) { //Just go back to position of current frame nRetVal = SeekStream(XN_OS_SEEK_SET, pPlayerNodeInfo->nLastDataPos); XN_IS_STATUS_OK(nRetVal); } else if (nDestFrame < nNextFrame) { //Seek backwards XnUInt32 nDestRecordPos = pPlayerNodeInfo->newDataUndoInfo.nRecordPos; XnUInt32 nUndoRecordPos = pPlayerNodeInfo->newDataUndoInfo.nUndoRecordPos; NewDataRecordHeader record(m_pRecordBuffer, RECORD_MAX_SIZE); /*Scan back through the frames' undo positions until we get to a frame number that is smaller or equal to nDestFrame. We put the position of the frame we find in nDestRecordPos. */ do { if (nUndoRecordPos == 0) { /* The last frame we encountered doesn't have an undo frame. But this data frame can't be the first, so the file is corrupt */ XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Undo frame not found for frame in position %u", nDestRecordPos); } nRetVal = SeekStream(XN_OS_SEEK_SET, nUndoRecordPos); XN_IS_STATUS_OK(nRetVal); nDestRecordPos = nUndoRecordPos; record.ResetRead(); nRetVal = ReadRecordHeader(record); XN_IS_STATUS_OK(nRetVal); if (record.GetType() != RECORD_NEW_DATA) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Unexpected record type: %u", record.GetType()); } if (record.GetNodeID() != nNodeID) { XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Unexpected node id: %u", record.GetNodeID()); } nRetVal = ReadRecordFields(record); XN_IS_STATUS_OK(nRetVal); nRetVal = record.Decode(); XN_IS_STATUS_OK(nRetVal); nUndoRecordPos = record.GetUndoRecordPos(); } while (record.GetFrameNumber() > nDestFrame); //Now handle the frame nRetVal = HandleNewDataRecord(record, FALSE); XnBool bUndone = FALSE; for (XnUInt32 i = 0; i < m_nMaxNodes; i++) { //Rollback all properties to match the state the stream was in at position nDestRecordPos PlayerNodeInfo &pni = m_pNodeInfoMap[i]; for (RecordUndoInfoMap::Iterator it = pni.recordUndoInfoMap.begin(); it != pni.recordUndoInfoMap.end(); it++) { if ((it.Value().nRecordPos > nDestRecordPos) && (it.Value().nRecordPos < nStartPos)) { //This property was set between nDestRecordPos and our start position, so we need to undo it. nRetVal = UndoRecord(it.Value(), nDestRecordPos, bUndone); XN_IS_STATUS_OK(nRetVal); } } if ((i != nNodeID) && pni.bIsGenerator) { //Undo all other generator nodes' data RecordUndoInfo &undoInfo = pni.newDataUndoInfo; if ((undoInfo.nRecordPos > nDestRecordPos) && (undoInfo.nRecordPos < nStartPos)) { nRetVal = UndoRecord(undoInfo, nDestRecordPos, bUndone); XN_IS_STATUS_OK(nRetVal); if (!bUndone) { //We couldn't find a record that can undo this data record pni.nLastDataPos = 0; pni.newDataUndoInfo.Reset(); } } } } /*Now, for each node, go to the position of the last encountered data record, and process that record (including its payload).*/ /*TODO: Optimization: remember each node's last data pos, and later, see if it changes. Only process data frames of nodes whose last data pos actually changed.*/ nRetVal = ProcessEachNodeLastData(nNodeID); XN_IS_STATUS_OK(nRetVal); } else //(nDestFrame >= nNextFrame) { //Skip all frames until we get to our frame number, but handle any properties we run into. while (pPlayerNodeInfo->nCurFrame < nDestFrame) { nRetVal = ProcessRecord(FALSE); XN_IS_STATUS_OK(nRetVal); } /*Now, for each node, go to the position of the last encountered data record, and process that record (including its payload).*/ /*TODO: Optimization: remember each node's last data pos, and later, see if it changes. Only process data frames of nodes whose last data pos actually changed.*/ nRetVal = ProcessEachNodeLastData(nNodeID); XN_IS_STATUS_OK(nRetVal); } return XN_STATUS_OK; }
XnStatus PlayerNode::SkipRecordPayload(Record record) { return SeekStream(XN_OS_SEEK_CUR, record.GetPayloadSize()); }
XnStatus PlayerNode::SeekToTimeStampAbsolute(XnUInt64 nDestTimeStamp) { XnStatus nRetVal = XN_STATUS_OK; XnUInt64 nRecordTimeStamp = 0LL; XnUInt32 nStartPos = TellStream(); //We'll revert to this in case nDestTimeStamp is beyond end of stream XN_IS_STATUS_OK(nRetVal); if (nDestTimeStamp < m_nTimeStamp) { nRetVal = Rewind(); } else if (nDestTimeStamp == m_nTimeStamp) { //Nothing to do return XN_STATUS_OK; } else if (nDestTimeStamp > m_nGlobalMaxTimeStamp) { nDestTimeStamp = m_nGlobalMaxTimeStamp; } Record record(m_pRecordBuffer, RECORD_MAX_SIZE); XnBool bEnd = FALSE; XnUInt32 nBytesRead = 0; while ((nRecordTimeStamp < nDestTimeStamp) && !bEnd) { nRetVal = ReadRecordHeader(record); XN_IS_STATUS_OK(nRetVal); switch (record.GetType()) { case RECORD_NEW_DATA: { //We already read Record::HEADER_SIZE, now read the rest of the new data record header nRetVal = Read(m_pRecordBuffer + Record::HEADER_SIZE, NewDataRecordHeader::MAX_SIZE - Record::HEADER_SIZE, nBytesRead); XN_IS_STATUS_OK(nRetVal); if (nBytesRead < NewDataRecordHeader::MAX_SIZE - Record::HEADER_SIZE) { return XN_STATUS_CORRUPT_FILE; } NewDataRecordHeader newDataRecordHeader(record); nRetVal = newDataRecordHeader.Decode(); XN_IS_STATUS_OK(nRetVal); //Save record time stamp nRecordTimeStamp = newDataRecordHeader.GetTimeStamp(); if (nRecordTimeStamp >= nDestTimeStamp) { //We're done - move back to beginning of record nRetVal = SeekStream(XN_OS_SEEK_CUR, -XnInt32(nBytesRead)); XN_IS_STATUS_OK(nRetVal); } else { //Skip to next record nRetVal = SeekStream(XN_OS_SEEK_CUR, newDataRecordHeader.GetSize() - NewDataRecordHeader::MAX_SIZE); XN_IS_STATUS_OK(nRetVal); } break; } case RECORD_END: { bEnd = TRUE; break; } case RECORD_NODE_ADDED_1_0_0_4: case RECORD_NODE_ADDED: case RECORD_INT_PROPERTY: case RECORD_REAL_PROPERTY: case RECORD_STRING_PROPERTY: case RECORD_GENERAL_PROPERTY: case RECORD_NODE_REMOVED: case RECORD_NODE_DATA_BEGIN: case RECORD_NODE_STATE_READY: { //Read rest of record and handle it normally nRetVal = Read(m_pRecordBuffer + Record::HEADER_SIZE, record.GetSize() - Record::HEADER_SIZE, nBytesRead); XN_IS_STATUS_OK(nRetVal); Record record(m_pRecordBuffer, RECORD_MAX_SIZE); nRetVal = HandleRecord(record, TRUE); XN_IS_STATUS_OK(nRetVal); break; } default: { XN_ASSERT(FALSE); return XN_STATUS_CORRUPT_FILE; } } //switch } //while if (bEnd) { SeekStream(XN_OS_SEEK_SET, nStartPos); return XN_STATUS_ILLEGAL_POSITION; } return XN_STATUS_OK; }//function
unsigned long DIGCLIENT DIGCliSeek( dig_fhandle h, unsigned long p, dig_seek k ) { return( SeekStream( h, p, k ) ); }
HELPIO long int HelpTell( HelpFp fp ) { return( SeekStream( (file_handle)fp, 0, DIO_SEEK_CUR ) ); }
HELPIO long int HelpSeek( HelpFp fp, long int offset, HelpSeekType where ) { return( SeekStream( (file_handle)fp, offset, seekTypeConvTable[where] ) ); }
unsigned long DIGCLIENTRY( Seek )( dig_fhandle fid, unsigned long p, dig_seek k ) { return( SeekStream( DIG_FID2PH( fid ), p, k ) ); }