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); }
XN_C_API XnStatus XN_C_DECL xnOSCreateSharedMemory(const XnChar* strName, XnUInt32 nSize, XnUInt32 nAccessFlags, XN_SHARED_MEMORY_HANDLE* phSharedMem) { return xnOSCreateSharedMemoryEx(strName, nSize, nAccessFlags, FALSE, phSharedMem); }
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", (XnUInt32)procID, m_strDeviceName, GetName()); nRetVal = m_SharedBufferName.UnsafeUpdateValue(strSharedName); XN_IS_STATUS_OK(nRetVal); nRetVal = RequiredSizeProperty().UnsafeUpdateValue(nMaxBufferSize); XN_IS_STATUS_OK(nRetVal); nRetVal = xnOSCreateSharedMemoryEx(strSharedName, nSharedBufferSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, m_bAllowOtherUsers, &m_hSharedMemory); XN_IS_STATUS_OK(nRetVal); XnUChar* pAddress; nRetVal = xnOSSharedMemoryGetAddress(m_hSharedMemory, (void**)&pAddress); XN_IS_STATUS_OK(nRetVal); m_pSharedHeader = (XnAudioSharedBuffer*)pAddress; m_buffer.pAudioPacketsTimestamps = (XnUInt64*)(pAddress + sizeof(XnAudioSharedBuffer)); m_buffer.pAudioBuffer = (XN_AUDIO_TYPE*)(pAddress + sizeof(XnAudioSharedBuffer) + sizeof(XnUInt64) * nMaxPacketCount); m_buffer.nAudioBufferSize = nMaxBufferSize; m_pSharedHeader->nTimestampsListOffset = sizeof(XnAudioSharedBuffer); m_pSharedHeader->nBufferOffset = (XnUInt32)(m_buffer.pAudioBuffer - pAddress); } // calculate current packet size m_buffer.nAudioPacketSize = m_nOrigAudioPacketSize; if (m_Helper.GetFirmwareVersion() >= XN_SENSOR_FW_VER_5_2 && GetNumberOfChannels() == 1) { m_buffer.nAudioPacketSize /= 2; } m_buffer.nAudioBufferNumOfPackets = m_buffer.nAudioBufferSize / m_buffer.nAudioPacketSize; m_buffer.nAudioBufferSize = m_buffer.nAudioBufferNumOfPackets * m_buffer.nAudioPacketSize; m_pSharedHeader->nPacketCount = m_buffer.nAudioBufferNumOfPackets; m_pSharedHeader->nPacketSize = m_buffer.nAudioPacketSize; // set read and write indices m_buffer.nAudioReadIndex = 0; m_buffer.nAudioWriteIndex = 0; return (XN_STATUS_OK); }