OpenNI2 内存管理

 

OpenNI2中主要涉及到内存管理部分的主要是(Depth, IR, Color)Frame buffer 部分,应用层通过OpenNI API可以获取到底层硬件传感器的各种数据,主要还是深度数据,红外图像数据,彩色图像数据。这其中就涉及到内存分配,引用,销毁一个完整的内存操作闭环。
以下从获取一帧深度数据的完整流程来具体分析Openni是如果管理内存的。

 

 

1.驱动层
    驱动数据接口一般是USB,收到一帧数据后驱动层会去分配内存存放数据,调用的函数接口为:getServices().acquireFrame()
-->
OniFrame* Sensor::acquireFrame()
{
 OniFrameInternal* pResult = m_frameManager.acquireFrame();
 if (pResult == NULL)
 {
  return NULL;
 }
 pResult->data = m_allocFrameBufferCallback(m_requiredFrameSize, m_frameBufferAllocatorCookie);
 if (pResult->data == NULL)
 {
  m_frameManager.release(pResult);
  return NULL;
 }
 pResult->dataSize = m_requiredFrameSize;
 pResult->backToPoolFunc = frameBackToPoolCallback;
 pResult->backToPoolFuncCookie = this;
 pResult->freeBufferFunc = m_freeFrameBufferCallback;
 pResult->freeBufferFuncCookie = m_frameBufferAllocatorCookie;
 xnl::AutoCSLocker lock(m_framesCS);
 m_currentStreamFrames.AddLast(pResult);
 return pResult;
}

 

 

首先调用到了frameManager 里面的acquireFrame()
OniFrameInternal* FrameManager::acquireFrame()
{
 OniFrameInternal* pFrame = m_frames.Acquire();
 // reset all fields
 pFrame->dataSize = 0;
 pFrame->data = NULL; //此时的内存还没有分配
 pFrame->sensorType = (OniSensorType)0;
 pFrame->timestamp = 0;
 pFrame->frameIndex = 0;
 pFrame->width = 0;
 pFrame->height = 0;
 pFrame->videoMode.pixelFormat = (OniPixelFormat)0;
 pFrame->videoMode.resolutionX = 0;
 pFrame->videoMode.resolutionY = 0;
 pFrame->videoMode.fps = 0;
 pFrame->croppingEnabled = FALSE;
 pFrame->cropOriginX = 0;
 pFrame->cropOriginY = 0;
 pFrame->stride = 0;
 pFrame->backToPoolFunc = NULL;
 pFrame->backToPoolFuncCookie = NULL;
 pFrame->refCount = 1; // this is the only reference
 pFrame->freeBufferFunc = NULL;
 pFrame->freeBufferFuncCookie = NULL;
 return pFrame;
}
 
该函数创建了一个空的OniFrameInternal结构,里面的参数需要在接下来填充。紧接着要去做真正的内存分配: m_allocFrameBufferCallback(),该函数是需要用户配置的回调函数,默认采用系统设置的:
Sensor::Sensor(xnl::ErrorLogger& errorLogger, FrameManager& frameManager, const DriverHandler& driverHandler) :
 m_streamCount(0),
 m_startedStreamCount(0),
 m_errorLogger(errorLogger),
 m_frameManager(frameManager),
 m_driverHandler(driverHandler),
 m_streamHandle(NULL),
 m_requiredFrameSize(0)
{
 resetFrameAllocator();
 OniStreamServices::streamServices = this;
 OniStreamServices::getDefaultRequiredFrameSize = getDefaultRequiredFrameSizeCallback;
 OniStreamServices::acquireFrame = acquireFrameCallback;
 OniStreamServices::addFrameRef = addFrameRefCallback;
 OniStreamServices::releaseFrame = releaseFrameCallback;

}
如果在回调函数中没有设置分配函数,引用函数,销毁函数(acquireFrame,addFrameRef , releaseFrame)那么 系统将采用默认配置:void Sensor::resetFrameAllocator()
{
 m_allocFrameBufferCallback = allocFrameBufferFromPoolCallback;
 m_freeFrameBufferCallback = releaseFrameBufferToPoolCallback;
 m_frameBufferAllocatorCookie = this;
}
void* Sensor::allocFrameBufferFromPool(int size)
{
 XN_ASSERT(size == m_requiredFrameSize);
 void* pResult = NULL;
 xnl::AutoCSLocker lock(m_framesCS);
 if (m_availableFrameBuffers.IsEmpty())
 {
  // create a new one
  pResult = xnOSMallocAligned(size, XN_DEFAULT_MEM_ALIGN);
  m_allFrameBuffers.AddLast(pResult);
 }
 else
 {
  xnl::List<void*>::Iterator it = m_availableFrameBuffers.Begin();
  pResult = *it;
  m_availableFrameBuffers.Remove(it);
 }
 return pResult;
}
allocFrameBufferFromPool()函数中开始真正分配内存xnOSMallocAligned(),前提是在当前可用Frame list上没有可用内存。当然提一次分配时list肯定为空,接下来会分析不为空的情况。分配成功后会把该内存放到m_allFrameBuffers 链表上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值