您的位置:首页 > 运维架构 > 网站架构

Android Camera 系统架构源码分析(5)---->Camera数据Buf的传递方式及相关类

2015-10-26 16:41 701 查看
写到第五篇,我们已经把大致的流程已经贯穿完了,还有很多东西没有讲,日后慢慢再说。不过现在有一个重要的问题,就是整个流利里各种buf,provider,bufmgr,queue类等之间的关系,说白了就是buf类和buf辅助类之前的关系。理清这些类的关系和这些类的作用,再从Buf流理解一下整个框架,CamAdapter和CamClient是怎么通过Buf联系,会对日后的分析有一个很大的帮助。也相当于对本文的一个总结。本来为了避免贴太多代码,想直接写中文总结的,后来发现贴代码虽然看得更辛苦一点,但细节更清晰,还是贴代码吧

DisplayClient::onThreadLoop(Commandconst&rCmd)
{
//(0)lockProcessor.
//pImgBufQueue的实现在ImgBufQueue.cpp里
sp<IImgBufQueue>pImgBufQueue;
pImgBufQueue=mpImgBufQueue;
/**(1)PrepareallTODObuffers.
pImgBufQueue里有两个Buf队列mTodoImgBufQue和mDoneImgBufQue
下面的函数用StreamImgBuf生成好ImgBufQueNode,把buf的标志位设为eSTATUS_TODO
后调用ImgBufQueue的enqueProcessor()把所有的Buf都放入到mTodoImgBufQue做接收数据的准备
**/
prepareAllTodoBuffers(pImgBufQueue);
//(2)Start只是通知队列,不做任何队列的数据处理
pImgBufQueue->startProcessor();
//(3)Dountildisabled.
while(1)
{
/**(.1)在此处会ImgBufQueue的dequeProcessor()等待通知,并接收数据
收到通知后,接收的是mDoneImgBufQue,一个ImgBufQueNode队列
接收到队列后把整个mDoneImgBufQue传入handleReturnBuffers()中被处理
handleReturnBuffers()首先会获得单个ImgBufQueNode中的IImgBuf,即最原始的Mem
		接下来就是操作mem。中途还有一些逻辑和StreamImgBuf有关联,现在忽略
	**/
waitAndHandleReturnBuffers(pImgBufQueue);
//(.2)breakifdisabled.
if(!isDisplayEnabled())
{
MY_LOGI("Displaydisabled");
break;
}
//又把buf放加到mTodoImgBufQue
prepareAllTodoBuffers(pImgBufQueue);
}
//
//(4)Stop
//退出,并清除队列,把BufQueNode标志位设为eSTATUS_CANCEL
pImgBufQueue->pauseProcessor();
pImgBufQueue->flushProcessor();
pImgBufQueue->stopProcessor();
}


看到这里我们了解到了
ImgBufQueNode为基本buf,里面包装了一个IImgBuf,用于操作内存存储

ImgBufQueue继承于IImgBufQueue和IImgBufProvider,是一个ImgBufQueNode队列的管理器,里面包含两条buf队列,一个是mTodoImgBufQue,一个是mDoneImgBufQue,里面装载着两种不同状态的buf,会把闲置的buf放入todo里,装好数据的buf装到done里,等待处理。在ImgBufQueue里有两个系列的函数

Process系列:

virtualboolenqueProcessor(ImgBufQueNodeconst&rNode)=0;
virtualbooldequeProcessor(Vector<ImgBufQueNode>&rvNode)=0;
//
virtualboolstartProcessor()=0;
virtualboolpauseProcessor()=0;
virtualboolflushProcessor()=0;
virtualboolstopProcessor()=0;


Provider系列

virtualbooldequeProvider(ImgBufQueNode&rNode)=0;
virtualboolenqueProvider(ImgBufQueNodeconst&rNode)=0;
virtualboolqueryProvider(ImgBufQueNode&rNode)=0;


这些系统函数都继承于他们的父类,其中Process系列的我们已经都看到了,只要给DisplayClient内部用于负责操作mTodoImgBufQue和mDoneImgBufQue的数据进出。但我们根据立面的分析知道,DisplayClient的数据由外部的CamAdapter提供,接下来就从CamAdapter角度来分析:

/**
CamAdapter继承了IImgBufProviderClient。并实现了onImgBufProviderCreated()函数
DisplayClient的setImgBufProviderClient(),传入了一个CamAdapter,即IImgBufProviderClient
并调用CamAdapter的onImgBufProviderCreated,传入参数是ImgBufQueue。即IImgBufProvider
**/
BaseCamAdapter::onImgBufProviderCreated(sp<IImgBufProvider>const&rpProvider)
{
int32_tconsti4ProviderId=rpProvider->getProviderId();
//把ImgBufQueue放入ImgBufProvidersManager
//此时ImgBufProvidersManager就拥有了DisplayClient和CamClient的数据队列ImgBufQueue
mpImgBufProvidersMgr->setProvider(i4ProviderId,rpProvider);
}
/**
我们直接跑到PreviewCmdQueThread的UpdateOne(),在此函数里,从Sensor接收并处理完数据后
会把Buf传给mspPreviewBufHandler
**/
PreviewCmdQueThread::updateOne()
{
//从DisplayClient的ImgBufQueue的mTodoImgBufQue取出Buf
	mspPreviewBufHandler->dequeBuffer(eID_Pass2DISPO,dispNode);
//mspPreviewBufHandler的实现是PreviewBufMgr,PreviewBufMgr的继承关系是
//PreviewBufMgr-->IPreviewBufMgr-->IPreviewBufMgrHandler
dispNode.getImgBuf()->setTimestamp(pass1LatestTimeStamp);
//把Buf放到DisplayClient的ImgBufQueue的mDoneImgBufQue
mspPreviewBufHandler->enqueBuffer(dispNode);
}
PreviewBufMgr::enqueBuffer(ImgBufQueNodeconst&node)
{
//(2)choosethecorrect"client"
switch(node.getCookieDE())
{
caseeBuf_Pass1:
//...
caseeBuf_Disp:
{
//从ImgBufProvidersManager找出Provider,这里即我们的DisplayClient的ImgBufQueue
sp<IImgBufProvider>bufProvider=mspImgBufProvidersMgr->getDisplayPvdr();
if(bufProvider!=0)
{
//调用DisplayClient的ImgBufQueue
bufProvider->enqueProvider(node);
}
}
break;
//
caseeBuf_AP:
//...
caseeBuf_FD:
//...
caseeBuf_Rec:
//...
}
}
//DisplayClitn的ImgBufQueue
ImgBufQueue::enqueProvider(ImgBufQueNodeconst&rNode)
{
mDoneImgBufQue.push_back(rNode);
mDoneImgBufQueCond.broadcast();
}


看到这里我们又知道了:

IImgBufProviderClient是用来管理IImgBufProvider,即让CamAdapter通过ImgBufProvidersManager管理DisplayClient的IImgBufProvider



这里的IImgBufProvider是我们DiaplayClient数据队列的管理者ImgBufQueue的父类。管理着mTodoImgBufQue和mDoneImgBufQue

上面说了ImgBufQueue继承了Provider和Process,并实现了他们的函数,其中Provider是提供给外部的类提出数据包和插入数据包,而Process是用来给内部整理和读取数据包。就如我们的DisplayClient的ImgBufQueue,DisplayClient内部生成和读取Buf通过Process系列函数,而DisplayClient把Provider系列函数提供给了CamAdapter操作数据包

这里还涉及了两个外部管理类,ImgBufProvidersManager和PreviewBufMgr,他们的继承关系是:

ImgBufProvidersManager-->RefBase



PreviewBufMgr-->IPreviewBufMgr-->IPreviewBufMgrHandler



ImgBufProvidersManager是用来管理ImgBufQueue,DisplayClient和CamClient都在它的管理内



PreviewBufMgr则是提取Provider的数据包,并填充数据再按数据包的作用通过ImgBufProvidersManager找到相应的Provider,把数据传给Provider

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: