/***************************************************************************** * * * PrimeSense Sensor 5.x Alpha * * Copyright (C) 2012 PrimeSense Ltd. * * * * This file is part of PrimeSense Sensor * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * * * *****************************************************************************/ //--------------------------------------------------------------------------- // Includes //--------------------------------------------------------------------------- #include "XnDeviceFileWriter.h" #include #include #include "XnDeviceFile.h" //--------------------------------------------------------------------------- // Code //--------------------------------------------------------------------------- XnDeviceFileWriter::XnDeviceFileWriter() : XnStreamWriterDevice(XN_DEVICE_NAME, XN_DEVICE_FILE_MAX_INTERNAL_BUFFER), m_bTimerStarted(FALSE) { } XnDeviceFileWriter::~XnDeviceFileWriter() { } XnStatus XnDeviceFileWriter::Destroy() { if (m_bTimerStarted) { xnOSStopTimer(&m_Timer); m_bTimerStarted = FALSE; } return XnStreamWriterDevice::Destroy(); } XnStatus XnDeviceFileWriter::CreateStream(const XnChar* StreamType, const XnChar* StreamName /* = NULL */, const XnPropertySet* pInitialValues /* = NULL */) { XnStatus nRetVal = XN_STATUS_OK; // create stream using base (this will also write it down to the file) nRetVal = XnStreamWriterDevice::CreateStream(StreamType, StreamName, pInitialValues); XN_IS_STATUS_OK(nRetVal); // now, we leave a place for a property change - the number of frames. We will update this // property once the stream is closed. XnFileWriterStream* pStream; nRetVal = FindStream(StreamName, &pStream); XN_IS_STATUS_OK(nRetVal); nRetVal = GetIOStream()->Tell(&pStream->m_nNumFramesPos); XN_IS_STATUS_OK(nRetVal); nRetVal = GetDataPacker()->WriteProperty(StreamName, XN_STREAM_PROPERTY_NUMBER_OF_FRAMES, 0ULL); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); } XnStatus XnDeviceFileWriter::DestroyStream(const XnChar* StreamName) { XnStatus nRetVal = XN_STATUS_OK; // before closing this stream, we want to write down how many frames were written XnFileWriterStream* pStream; nRetVal = FindStream(StreamName, &pStream); XN_IS_STATUS_OK(nRetVal); XnUInt64 nCurPos; nRetVal = GetIOStream()->Tell(&nCurPos); XN_IS_STATUS_OK(nRetVal); nRetVal = GetIOStream()->Seek(pStream->m_nNumFramesPos); XN_IS_STATUS_OK(nRetVal); nRetVal = GetDataPacker()->WriteProperty(StreamName, XN_STREAM_PROPERTY_NUMBER_OF_FRAMES, pStream->GetNumberOfFrames()); XN_IS_STATUS_OK(nRetVal); // now seek back nRetVal = GetIOStream()->Seek(nCurPos); XN_IS_STATUS_OK(nRetVal); // and destroy it nRetVal = XnStreamWriterDevice::DestroyStream(StreamName); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); } XnStatus XnDeviceFileWriter::WriteStream(XnStreamData* pStreamOutput) { XnStatus nRetVal = XN_STATUS_OK; // start the timer on the first data written nRetVal = StartTimer(); XN_IS_STATUS_OK(nRetVal); // fill in timestamp if needed if (pStreamOutput->nTimestamp == 0) { XnUInt64 nNow; xnOSQueryTimer(m_Timer, &nNow); if (!IsHighResTimestamps()) { nNow /= 1000; } pStreamOutput->nTimestamp = nNow; } // and write it down (using base) nRetVal = XnStreamWriterDevice::WriteStream(pStreamOutput); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); } XnStatus XnDeviceFileWriter::Write(XnStreamDataSet* pStreamOutputSet) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(pStreamOutputSet); // get a list of objects in the set XnStreamData* aOutputs[XN_DEVICE_BASE_MAX_STREAMS_COUNT]; XnUInt32 nCount = XN_DEVICE_BASE_MAX_STREAMS_COUNT; nRetVal = XnStreamDataSetCopyToArray(pStreamOutputSet, aOutputs, &nCount); XN_IS_STATUS_OK(nRetVal); // BC: old applications wrote down all streams every frame, even if no new data. This might // cause some of the streams to have timestamp 0, while other have a real timestamp. // In this case, remove these frames. However, we need to check - if all timestamps // are 0, then we'll fill it up by ourselves. XnBool bSomeHasTimestamps = FALSE; for (XnUInt32 i = 0; i < nCount; ++i) { if (aOutputs[i]->nTimestamp != 0) { bSomeHasTimestamps = TRUE; break; } } if (bSomeHasTimestamps) { // remove all the ones with zero timestamp for (XnUInt32 i = 0; i < nCount; ++i) { if (aOutputs[i]->nTimestamp == 0) { aOutputs[i]->bIsNew = FALSE; } } } // OK. write it down using base nRetVal = XnStreamWriterDevice::Write(pStreamOutputSet); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); } XnStatus XnDeviceFileWriter::StartTimer() { XnStatus nRetVal = XN_STATUS_OK; if (!m_bTimerStarted) { nRetVal = xnOSStartHighResTimer(&m_Timer); XN_IS_STATUS_OK(nRetVal); m_bTimerStarted = TRUE; } return (XN_STATUS_OK); } XnStatus XnDeviceFileWriter::CreateStreamModule(const XnChar* StreamType, const XnChar* StreamName, XnDeviceModuleHolder** ppStreamHolder) { XnFileWriterStream* pStream; XN_VALIDATE_NEW(pStream, XnFileWriterStream, StreamType, StreamName, GetDataPacker()); XnStreamDeviceStreamHolder* pHolder = XN_NEW(XnStreamDeviceStreamHolder, pStream, FALSE); if (pHolder == NULL) { XN_DELETE(pStream); return XN_STATUS_ALLOC_FAILED; } *ppStreamHolder = pHolder; return (XN_STATUS_OK); } void XnDeviceFileWriter::DestroyStreamModule(XnDeviceModuleHolder* pStreamHolder) { XN_DELETE(pStreamHolder->GetModule()); XN_DELETE(pStreamHolder); } XnStatus XnDeviceFileWriter::CreateIOStreamImpl(const XnChar* strConnectionString, XnIOStream*& pStream) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_NEW_AND_INIT(pStream, XnIOFileStream, strConnectionString, XN_OS_FILE_WRITE | XN_OS_FILE_TRUNCATE); // write down the magic nRetVal = pStream->WriteData((const XnUChar*)XN_DEVICE_FILE_MAGIC_V4, (XnUInt32)strlen(XN_DEVICE_FILE_MAGIC_V4)); if (nRetVal != XN_STATUS_OK) { XN_DELETE(pStream); pStream = NULL; return (nRetVal); } return (XN_STATUS_OK); } void XnDeviceFileWriter::DestroyIOStreamImpl(XnIOStream* pStream) { pStream->Free(); XN_DELETE(pStream); } XnStatus XnDeviceFileWriter::FindStream(const XnChar* strName, XnFileWriterStream** ppStream) { XnStatus nRetVal = XN_STATUS_OK; XnStreamDeviceStreamHolder* pHolder = NULL; nRetVal = XnStreamWriterDevice::FindStream(strName, &pHolder); XN_IS_STATUS_OK(nRetVal); *ppStream = (XnFileWriterStream*)pHolder->GetStream(); return (XN_STATUS_OK); }