XnStatus XnFrameStream::GetTripleBuffer(XnFrameBufferManager** pBufferManager) { XnStatus nRetVal = XN_STATUS_OK; // lazy initialization (this allows us to set buffer pool after initialization of the stream // and before data actually arrives (or stream data is allocated) if (m_pBufferManager == NULL) { if (m_pBufferPool == NULL) { XN_VALIDATE_NEW(m_pBufferPool, XnSimpleBufferPool, 3); m_bPoolAllocated = TRUE; nRetVal = m_pBufferPool->Init(GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); } // allocate buffer manager XN_VALIDATE_NEW(m_pBufferManager, XnFrameBufferManager, m_pBufferPool); nRetVal = m_pBufferManager->Init(GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); // register for new data events XnCallbackHandle hDummy; nRetVal = m_pBufferManager->OnNewFrameEvent().Register(OnTripleBufferNewData, this, hDummy); XN_IS_STATUS_OK(nRetVal); } *pBufferManager = m_pBufferManager; return (XN_STATUS_OK); }
XnStatus XnFrameStream::Init() { XnStatus nRetVal = XN_STATUS_OK; // init base nRetVal = XnDeviceStream::Init(); XN_IS_STATUS_OK(nRetVal); XN_VALIDATE_ADD_PROPERTIES(this, &m_IsFrameStream, &m_FPS, &m_LastRawFrame); XnCallbackHandle hDummy; // be notified when required size changes nRetVal = RequiredSizeProperty().OnChangeEvent().Register(RequiredSizeChangedCallback, this, &hDummy); XN_IS_STATUS_OK(nRetVal); if (m_pBufferPool == NULL) { XN_VALIDATE_NEW(m_pBufferPool, XnSimpleBufferPool, 3); m_bPoolAllocated = TRUE; } // allocate buffer manager XN_VALIDATE_NEW(m_pBufferManager, XnFrameBufferManager, m_pBufferPool); nRetVal = m_pBufferManager->Init(GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); // register for new data events nRetVal = m_pBufferManager->OnNewFrameEvent().Register(OnTripleBufferNewData, this, &hDummy); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }
XnStatus XnFrameStream::SetExternalBufferPool(XnUInt32 nCount, XnGeneralBuffer* aBuffers) { XnStatus nRetVal = XN_STATUS_OK; if (m_pBufferPool != NULL) { xnLogError(XN_MASK_DDK, "Cannot change buffer pool."); return XN_STATUS_DEVICE_PROPERTY_READ_ONLY; } XnExternalBufferPool* pExternalBufferPool; XN_VALIDATE_NEW(pExternalBufferPool, XnExternalBufferPool); nRetVal = pExternalBufferPool->SetBuffers(nCount, aBuffers); if (nRetVal != XN_STATUS_OK) { XN_DELETE(pExternalBufferPool); return (nRetVal); } nRetVal = pExternalBufferPool->Init(GetRequiredDataSize()); if (nRetVal != XN_STATUS_OK) { XN_DELETE(pExternalBufferPool); return (nRetVal); } m_pBufferPool = pExternalBufferPool; return (XN_STATUS_OK); }
XnStatus XnStreamReaderStream::OnRequiredSizeChanged() { XnStatus nRetVal = XN_STATUS_OK; nRetVal = XnStreamDataUpdateSize(m_pLastData, GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }
XnStatus XnFrameStream::ReallocTripleFrameBuffer() { XnStatus nRetVal = XN_STATUS_OK; nRetVal = m_pBufferManager->Reallocate(GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); m_bTripleBufferReallocated = TRUE; return (XN_STATUS_OK); }
XnStatus XnSensorAudioStream::ReadImpl(XnStreamData *pStreamOutput) { XnStatus nRetVal = XN_STATUS_OK; XnDevicePrivateData* pDevicePrivateData = m_Helper.GetPrivateData(); pStreamOutput->nDataSize = 0; XN_AUDIO_TYPE* pAudioBuf = (XN_AUDIO_TYPE*)pStreamOutput->pData; xnOSEnterCriticalSection(&pDevicePrivateData->hAudioBufferCriticalSection); // check how many buffers we have XnInt32 nAvailbalePackets = pDevicePrivateData->nAudioWriteIndex - pDevicePrivateData->nAudioReadIndex; if (nAvailbalePackets < 0) nAvailbalePackets += pDevicePrivateData->nAudioBufferNumOfPackets; // now check if stream frame buffer has enough space if (GetRequiredDataSize() < (XnUInt32)nAvailbalePackets * pDevicePrivateData->nAudioPacketSize) { xnOSLeaveCriticalSection(&pDevicePrivateData->hAudioBufferCriticalSection); return (XN_STATUS_IO_INVALID_STREAM_AUDIO_BUFFER_SIZE); } // take first packet timestamp pStreamOutput->nTimestamp = pDevicePrivateData->pAudioPacketsTimestamps[pDevicePrivateData->nAudioReadIndex]; XnUChar* pPacketData = pDevicePrivateData->pAudioBuffer + (pDevicePrivateData->nAudioReadIndex * pDevicePrivateData->nAudioPacketSize); // copy while (pDevicePrivateData->nAudioReadIndex != pDevicePrivateData->nAudioWriteIndex) { xnOSMemCopy(pAudioBuf, pPacketData, pDevicePrivateData->nAudioPacketSize); pAudioBuf += pDevicePrivateData->nAudioPacketSize; pStreamOutput->nDataSize += pDevicePrivateData->nAudioPacketSize; pDevicePrivateData->nAudioReadIndex++; pPacketData += pDevicePrivateData->nAudioPacketSize; if (pDevicePrivateData->nAudioReadIndex == pDevicePrivateData->nAudioBufferNumOfPackets) { pDevicePrivateData->nAudioReadIndex = 0; pPacketData = pDevicePrivateData->pAudioBuffer; } } xnOSLeaveCriticalSection(&pDevicePrivateData->hAudioBufferCriticalSection); ++m_nFrameID; pStreamOutput->nFrameID = m_nFrameID; return (XN_STATUS_OK); }
XnStatus XnStreamReaderStream::Init() { XnStatus nRetVal = XN_STATUS_OK; nRetVal = XnDeviceStream::Init(); XN_IS_STATUS_OK(nRetVal); // register for size change (so we can realloc stream data) nRetVal = RequiredSizeProperty().OnChangeEvent().Register(RequiredSizeChangedCallback, this); XN_IS_STATUS_OK(nRetVal); // and create stream data nRetVal = XnStreamDataCreate(&m_pLastData, GetName(), GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }
XnStatus XnStreamReaderStream::ReadImpl(XnStreamData* pStreamData) { pStreamData->nFrameID = m_pLastData->nFrameID; pStreamData->nTimestamp = m_pLastData->nTimestamp; if (pStreamData->pInternal->bAllocated) { // don't take more than required size pStreamData->nDataSize = XN_MIN(m_pLastData->nDataSize, GetRequiredDataSize()); xnOSMemCopy(pStreamData->pData, m_pLastData->pData, pStreamData->nDataSize); } else { pStreamData->nDataSize = m_pLastData->nDataSize; pStreamData->pData = m_pLastData->pData; } return (XN_STATUS_OK); }
XnStatus XnFrameStream::CreateStreamData(XnStreamData** ppStreamData) { XnStatus nRetVal = XN_STATUS_OK; XnStreamData* pStreamData; // NOTE: in any case, we must make sure data is not null, because some old applications // counts on it (they might read the data before the first frame). // check if the buffer pool has been set yet if (m_pBufferPool == NULL) { // Create it with a buffer. This buffer will be later on freed when buffers from // the buffer pool will be used. nRetVal = XnStreamDataCreate(&pStreamData, GetName(), GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); } else { // we create a StreamData object with no buffer allocated. The buffer will just be // a pointer from the buffer pool nRetVal = XnStreamDataCreateNoBuffer(&pStreamData, GetName()); XN_IS_STATUS_OK(nRetVal); // take a buffer from the pool nRetVal = m_pBufferPool->GetBuffer(&pStreamData->pInternal->pLockedBuffer); if (nRetVal != XN_STATUS_OK) { XnStreamDataDestroy(&pStreamData); return (nRetVal); } pStreamData->pData = (void*)pStreamData->pInternal->pLockedBuffer->GetData(); } *ppStreamData = pStreamData; return (XN_STATUS_OK); }
XnStatus XnDeviceStream::Read(XnStreamData* pStreamOutput) { XnStatus nRetVal = XN_STATUS_OK; // check the size of the stream output object nRetVal = XnStreamDataCheckSize(pStreamOutput, GetRequiredDataSize()); XN_IS_STATUS_OK(nRetVal); // first mark old data as old pStreamOutput->bIsNew = FALSE; // now check if we have some new data if (m_bNewDataAvailable) { // copy data nRetVal = ReadImpl(pStreamOutput); XN_IS_STATUS_OK(nRetVal); xnOSEnterCriticalSection(&m_hCriticalSection); XnBool bMirror = IsMirrored(); xnOSLeaveCriticalSection(&m_hCriticalSection); // mirror it if needed if (bMirror) { nRetVal = Mirror(pStreamOutput); XN_IS_STATUS_OK(nRetVal); } // mark that data is new pStreamOutput->bIsNew = TRUE; // and that we don't have new info m_bNewDataAvailable = FALSE; } return (XN_STATUS_OK); }
XnStatus XnStreamWriterStream::CalcRequiredSize(XnUInt32* pnRequiredSize) const { // we use the same size we have now *pnRequiredSize = GetRequiredDataSize(); return XN_STATUS_OK; }
XnStatus XnDeviceStream::CreateStreamData(XnStreamData** ppStreamData) { return XnStreamDataCreate(ppStreamData, GetName(), GetRequiredDataSize()); }