一、初始化部分:
功能的初始化入口:StreamingFeaturePipeline::init
initNodes中会检查各功能支持标志位,如果支持,则把对应Node添加到List中。
接下来通过两个模板类的,实现调用不同Node的onInit方法,VSDOF功能对应DepthNode,这里以后都是为VSDOF功能定制的初始化流程。
有几个重点函数:
-
initializeBufferPool:
依次调用所需的各个Node对应的initxxxBuffPool
完成每个Node 需要的BufferPool创建,并完成allocate动作。
每种数据缓冲池中buffer的数量就是在这里allocate时完成配置 -
buildImageBufferPoolMap:
构建bufferPoolMap,将第一步中创建的BufferPool与特定的key值绑定,存储到map中。方便后续根据使用场景取用 -
TEST_AND_CREATE_NODE:
检查各Node支持情况,如果支持,则创建对应类的实例。并将前面流程中定义的mpNodeSignal, mpDepthStorage, mpBufferPoolMgr传入各个node中,用于共享。
各Node的构造函数中,主要完成:根据需要的数据,添加对应数量的addWaitQueue。 -
buildPipeGraph:
连接各个节点的数据流,完成图的构建。如下所示:
-
mCamGraph.start:
为各个Node起单独的线程,并执行onThreadLoop里面的流程
二、各个Node onThreadLoop的部分流程走向:
Node间的联系都是基于buildPipeGraph中创建的数据流走向。
三、缓冲池(buffer pool)中每个buffer的轮转流程
以N3DMaskBufPool_Main1为例:
- 创建buffer pool:
CREATE_IMGBUF_POOL(mN3DMaskBufPool_Main1, "N3DMaskBufPool_Main1", rN3DSize.mWARP_MASK_SIZE,
eImgFmt_Y8, usage, MTRUE);
- 分配空间
ALLOCATE_BUFFER_POOL(mN3DMaskBufPool_Main1, VSDOF_WORKING_BUF_SET);
- 添加到mBIDtoImgBufPoolMap_Scenario中,方便后续根据实际场景需求取用
MASKImgBufMap.add(eBUFFER_POOL_SCENARIO_PREVIEW, mN3DMaskBufPool_Main1);
mBIDtoImgBufPoolMap_Scenario.add(BID_N3D_OUT_MASK_M, MASKImgBufMap);
- Node的流程中通过bufferID(BID_N3D_OUT_MASK_M)定位需要获取的具体buffer
IImageBuffer* pImgBuf_MASK_M = pBufferHandler->requestBuffer(getNodeId(), BID_N3D_OUT_MASK_M);
requestbuffer方法中通过bufferID与使用场景获取到buffer pool——对应第3步中构建的map
并从buffer pool中取出一个buffer。
SmartImageBuffer smImgBuf = mpBufferPoolMgr->request(bufferID, mReqAttr.bufferScenario);
SmartImageBuffer NodeBufferPoolMgr_VSDOF::request(DepthMapBufferID id, BufferPoolScenario scen)
{
……
ssize_t index_2 = mBIDtoImgBufPoolMap_Scenario.indexOfKey(id);
if(index_2 >= 0)
{
ScenarioToImgBufPoolMap ScenarioBufMap = mBIDtoImgBufPoolMap_Scenario.valueAt(index_2);
if((index=ScenarioBufMap.indexOfKey(scen))>=0)
{
sp<ImageBufferPool> pBufferPool = ScenarioBufMap.valueAt(index);
return pBufferPool->request(); //出栈
}
}
……
}
- addEnquedBuffer方法构建BID buffer map:
将分配好的buffer添加到当前node对应的bidBufMap中
BIDToSmartBufferMap& bidBufMap = mEnqueBufferMap.editValueFor(srcNodeID);
bidBufMap.add(bufferID, smImgBuf);
- 针对申请到到buffer做Node对应的处理:
rN3dParam.maskMain1 = pImgBuf_MASK_M;
bRet = mpN3DHAL_VRPV->N3DHALRun(n3dParams, n3dOutput);
- 处理完成的数据传递给下一个目标Node
pBufferHandler->configOutBuffer(getNodeId(), BID_N3D_OUT_MASK_M, eDPETHMAP_PIPE_NODEID_DPE);
此方法主要完成从源Node的buffer Map(第五步中构建)中取出需要传递的buffer,并添加到目标Node的buffer Map中
queuedBufferMap = mEnqueBufferMap.valueFor(srcNodeID);
smBuf = queuedBufferMap.valueAt(bufIndex); //获取到对应buffer
this->addOutputBuffer(outNodeID, outBufferID, smBuf);
- 通知目标节点数据已就位
this->handleDataAndDump(N3D_TO_DPE_MVSV_MASK, pRequest);
调用目标节点的onDate,将对应的request添加到waitQueue中,然后在Node的onThreadLoop中从waitQueue中dequeue出来使用。
此处用到初始化流程第4步中buildPipeGraph方法构建的数据流向图
- 目标节点获取数据:
bRet &= pBufferHandler->getEnqueBuffer(getNodeId(), BID_N3D_OUT_MASK_M, pImgBuf_MASK_M);
从第7步中构建的buffer Map中去除对应的buffer,并传送到需要的位置做处理
rDPEConfigVec.push_back(dpeConfig);
- 完成处理流程后清理buffer并返还到buffer pool
pBufferHandler->onProcessDone(getNodeId());
遗留部分: