XnStatus XnSharedMemoryBufferPool::AllocateBuffers() { XnStatus nRetVal = XN_STATUS_OK; if (m_nBufferSize > m_nMaxBufferSize) { return XN_STATUS_ALLOC_FAILED; } if (m_pSharedMemoryAddress != NULL) { // already allocated. nothing to do here return (XN_STATUS_OK); } // first time. allocate shared memory XnUInt32 nTotalSize = m_nMaxBufferSize * m_nBufferCount; nRetVal = xnOSCreateSharedMemory(m_strName, nTotalSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, &m_hSharedMemory); XN_IS_STATUS_OK(nRetVal); void* pAddress; nRetVal = xnOSSharedMemoryGetAddress(m_hSharedMemory, &pAddress); if (nRetVal != XN_STATUS_OK) { xnOSCloseSharedMemory(m_hSharedMemory); m_hSharedMemory = NULL; return (nRetVal); } m_pSharedMemoryAddress = (XnUChar*)pAddress; // now allocate buffers for (XnUInt32 i = 0; i < m_nBufferCount; ++i) { XnBufferInPool* pBuffer = XN_NEW(XnBufferInPool); if (pBuffer == NULL) { Free(); return (XN_STATUS_ALLOC_FAILED); } pBuffer->m_nID = i; pBuffer->SetExternalBuffer(m_pSharedMemoryAddress + i*m_nMaxBufferSize, m_nMaxBufferSize); xnDumpWriteString(Dump(), "Allocated buffer %u with size %u\n", i, m_nMaxBufferSize); // add it to free list m_AllBuffers.AddLast(pBuffer); m_FreeBuffers.AddLast(pBuffer); } return (XN_STATUS_OK); }
XnStatus XnSensorAudioStream::ReallocBuffer() { XnStatus nRetVal = XN_STATUS_OK; XnDevicePrivateData* pDevicePrivateData = m_Helper.GetPrivateData(); if (m_hSharedMemory == NULL) { // first time, create shared memory // we allocate enough for 5 seconds of audio XnUInt32 nSampleSize = 2 * 2; // 16-bit per channel (2 bytes) * max number of channels (2) XnUInt32 nSamples = 48000 * 5; // max sample rate * number of seconds XnUInt32 nMaxBufferSize = nSamples * nSampleSize; // find min packet size (so we'll have max packet count) XnUInt32 nMinPacketSize = XN_MIN(XN_SENSOR_PROTOCOL_AUDIO_PACKET_SIZE_BULK, XN_SENSOR_PROTOCOL_AUDIO_PACKET_SIZE_ISO); XnUInt32 nMaxPacketCount = nMaxBufferSize / nMinPacketSize - 1; XnUInt32 nSharedBufferSize = sizeof(XnAudioSharedBuffer) + // header sizeof(XnUInt64) * nMaxPacketCount + // packet timestamps nMaxBufferSize; // to make the name unique, we'll add process ID XN_PROCESS_ID procID; xnOSGetCurrentProcessID(&procID); XnChar strSharedName[XN_DEVICE_MAX_STRING_LENGTH]; sprintf(strSharedName, "%u_%s_%s", procID, m_strDeviceName, GetName()); nRetVal = m_SharedBufferName.UnsafeUpdateValue(strSharedName); XN_IS_STATUS_OK(nRetVal); nRetVal = RequiredSizeProperty().UnsafeUpdateValue(nMaxBufferSize); XN_IS_STATUS_OK(nRetVal); nRetVal = xnOSCreateSharedMemory(strSharedName, nSharedBufferSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, &m_hSharedMemory); XN_IS_STATUS_OK(nRetVal); XnUChar* pAddress; nRetVal = xnOSSharedMemoryGetAddress(m_hSharedMemory, (void**)&pAddress); XN_IS_STATUS_OK(nRetVal); m_pSharedHeader = (XnAudioSharedBuffer*)pAddress; pDevicePrivateData->pAudioPacketsTimestamps = (XnUInt64*)(pAddress + sizeof(XnAudioSharedBuffer)); pDevicePrivateData->pAudioBuffer = (XN_AUDIO_TYPE*)(pAddress + sizeof(XnAudioSharedBuffer) + sizeof(XnUInt64) * nMaxPacketCount); pDevicePrivateData->nAudioBufferSize = nMaxBufferSize; m_pSharedHeader->nTimestampsListOffset = sizeof(XnAudioSharedBuffer); m_pSharedHeader->nBufferOffset = pDevicePrivateData->pAudioBuffer - pAddress; } // calculate current packet size pDevicePrivateData->nAudioPacketSize = m_nOrigAudioPacketSize; if (m_Helper.GetFirmwareVersion() >= XN_SENSOR_FW_VER_5_2 && GetNumberOfChannels() == 1) { pDevicePrivateData->nAudioPacketSize /= 2; } pDevicePrivateData->nAudioBufferNumOfPackets = pDevicePrivateData->nAudioBufferSize / pDevicePrivateData->nAudioPacketSize; pDevicePrivateData->nAudioBufferSize = pDevicePrivateData->nAudioBufferNumOfPackets * pDevicePrivateData->nAudioPacketSize; m_pSharedHeader->nPacketCount = pDevicePrivateData->nAudioBufferNumOfPackets; m_pSharedHeader->nPacketSize = pDevicePrivateData->nAudioPacketSize; // set read and write indices pDevicePrivateData->nAudioReadIndex = 0; pDevicePrivateData->nAudioWriteIndex = 0; return (XN_STATUS_OK); }
XnStatus XnServerSensorInvoker::SetStreamSharedMemory(SensorInvokerStream* pStream) { XnStatus nRetVal = XN_STATUS_OK; // give shared memory a name (to make the name unique, we'll add process ID) XN_PROCESS_ID procID; xnOSGetCurrentProcessID(&procID); XnChar strSharedMemoryName[XN_FILE_MAX_PATH]; sprintf(strSharedMemoryName, "%u_%s_%s", (XnUInt32)procID, m_sensor.GetUSBPath(), pStream->strType); nRetVal = pStream->pSharedMemoryName->UnsafeUpdateValue(strSharedMemoryName); XN_IS_STATUS_OK(nRetVal); XnUInt32 nBufferSize = 0; XnUInt32 nPixelSize = 0; if (strcmp(pStream->strType, XN_STREAM_TYPE_DEPTH) == 0) { // have space for depth and shift values nPixelSize = sizeof(XnDepthPixel) + sizeof(XnUInt16); } else if (strcmp(pStream->strType, XN_STREAM_TYPE_IMAGE) == 0) { // biggest pixel size is the RGB24 nPixelSize = sizeof(XnRGB24Pixel); } else if (strcmp(pStream->strType, XN_STREAM_TYPE_IR) == 0) { // biggest pixel size is the RGB24 nPixelSize = sizeof(XnIRPixel); } else { XN_ASSERT(FALSE); return XN_STATUS_ERROR; } // find out max resolution XnUInt32 nMaxNumPixels = 0; nRetVal = GetStreamMaxResolution(pStream, nMaxNumPixels); XN_IS_STATUS_OK(nRetVal); nBufferSize = (XnUInt32)(nMaxNumPixels * nPixelSize * m_numberOfBuffers.GetValue()); // allocate shared memory nRetVal = xnOSCreateSharedMemoryEx(strSharedMemoryName, nBufferSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, m_allowOtherUsers.GetValue() == TRUE, &pStream->hSharedMemory); XN_IS_STATUS_OK(nRetVal); nRetVal = xnOSSharedMemoryGetAddress(pStream->hSharedMemory, (void**)&pStream->pSharedMemoryAddress); XN_IS_STATUS_OK(nRetVal); // Set buffer pool for this stream XnGeneralBuffer* aBuffers = XN_NEW_ARR(XnGeneralBuffer, m_numberOfBuffers.GetValue()); XnUInt32 nSingleBufferSize = nBufferSize / m_numberOfBuffers.GetValue(); for (XnUInt32 i = 0; i < m_numberOfBuffers.GetValue(); ++i) { aBuffers[i].pData = pStream->pSharedMemoryAddress + (i * nSingleBufferSize); aBuffers[i].nDataSize = nSingleBufferSize; } nRetVal = m_sensor.SetProperty(pStream->strType, XN_STREAM_PROPERTY_EXTERNAL_BUFFER_POOL, XnGeneralBufferPack(aBuffers, m_numberOfBuffers.GetValue() * sizeof(XnGeneralBuffer))); XN_DELETE_ARR(aBuffers); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }