写到第五篇,我们已经把大致的流程已经贯穿完了,还有很多东西没有讲,日后慢慢再说。不过现在有一个重要的问题,就是整个流利里各种buf,provider,bufmgr,queue类等之间的关系,说白了就是buf类和buf辅助类之前的关系。理清这些类的关系和这些类的作用,再从Buf流理解一下整个框架,CamAdapter和CamClient是怎么通过Buf联系,会对日后的分析有一个很大的帮助。也相当于对本文的一个总结。本来为了避免贴太多代码,想直接写中文总结的,后来发现贴代码虽然看得更辛苦一点,但细节更清晰,还是贴代码吧
DisplayClient::onThreadLoop(Command const& rCmd){// (0) lock Processor.//pImgBufQueue的实现在ImgBufQueue.cpp里sp<IImgBufQueue> pImgBufQueue;pImgBufQueue = mpImgBufQueue;/** (1) Prepare all TODO buffers.pImgBufQueue里有两个Buf队列mTodoImgBufQue和mDoneImgBufQue下面的函数用StreamImgBuf生成好ImgBufQueNode,把buf的标志位设为eSTATUS_TODO后调用ImgBufQueue的enqueProcessor()把所有的Buf都放入到mTodoImgBufQue做接收数据的准备**/prepareAllTodoBuffers(pImgBufQueue);// (2) Start 只是通知队列,不做任何队列的数据处理pImgBufQueue->startProcessor();// (3) Do until disabled.while ( 1 ){/**(.1) 在此处会ImgBufQueue的dequeProcessor()等待通知,并接收数据收到通知后,接收的是mDoneImgBufQue,一个ImgBufQueNode队列接收到队列后把整个mDoneImgBufQue传入handleReturnBuffers()中被处理handleReturnBuffers()首先会获得单个ImgBufQueNode中的IImgBuf,即最原始的Mem接下来就是操作mem。中途还有一些逻辑和StreamImgBuf有关联,现在忽略**/waitAndHandleReturnBuffers(pImgBufQueue);// (.2) break if disabled.if ( ! isDisplayEnabled() ){MY_LOGI("Display disabled");break;}//又把buf放加到mTodoImgBufQueprepareAllTodoBuffers(pImgBufQueue);}//// (4) Stop//退出,并清除队列,把BufQueNode标志位设为eSTATUS_CANCELpImgBufQueue->pauseProcessor();pImgBufQueue->flushProcessor();pImgBufQueue->stopProcessor();}
看到这里我们了解到了
ImgBufQueNode为基本buf,里面包装了一个IImgBuf,用于操作内存存储
ImgBufQueue继承于IImgBufQueue和IImgBufProvider,是一个ImgBufQueNode队列的管理器,里面包含两条buf队列,一个是mTodoImgBufQue,一个是mDoneImgBufQue,里面装载着两种不同状态的buf,会把闲置的buf放入todo里,装好数据的buf装到done里,等待处理。在ImgBufQueue里有两个系列的函数
Process系列:
virtual bool enqueProcessor(ImgBufQueNode const& rNode) = 0;virtual bool dequeProcessor(Vector<ImgBufQueNode>& rvNode) = 0;//virtual bool startProcessor() = 0;virtual bool pauseProcessor() = 0;virtual bool flushProcessor() = 0;virtual bool stopProcessor() = 0;
Provider系列
virtual bool dequeProvider(ImgBufQueNode& rNode) = 0;virtual bool enqueProvider(ImgBufQueNode const& rNode) = 0;virtual bool queryProvider(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_t const i4ProviderId = rpProvider->getProviderId();//把ImgBufQueue放入ImgBufProvidersManager//此时ImgBufProvidersManager就拥有了DisplayClient和CamClient的数据队列ImgBufQueuempImgBufProvidersMgr->setProvider(i4ProviderId, rpProvider);}/**我们直接跑到PreviewCmdQueThread的UpdateOne(),在此函数里,从Sensor接收并处理完数据后会把Buf传给mspPreviewBufHandler**/PreviewCmdQueThread::updateOne(){//从DisplayClient的ImgBufQueue的mTodoImgBufQue取出BufmspPreviewBufHandler->dequeBuffer(eID_Pass2DISPO, dispNode);//mspPreviewBufHandler的实现是PreviewBufMgr,PreviewBufMgr的继承关系是//PreviewBufMgr-->IPreviewBufMgr-->IPreviewBufMgrHandlerdispNode.getImgBuf()->setTimestamp(pass1LatestTimeStamp);//把Buf放到DisplayClient的ImgBufQueue的mDoneImgBufQuemspPreviewBufHandler->enqueBuffer(dispNode);}PreviewBufMgr::enqueBuffer(ImgBufQueNode const& node){// (2) choose the correct "client"switch (node.getCookieDE()){case eBuf_Pass1://...case eBuf_Disp:{//从ImgBufProvidersManager找出Provider,这里即我们的DisplayClient的ImgBufQueuesp<IImgBufProvider> bufProvider = mspImgBufProvidersMgr->getDisplayPvdr();if (bufProvider != 0){//调用DisplayClient的ImgBufQueuebufProvider->enqueProvider(node);}}break;//case eBuf_AP://...case eBuf_FD://...case eBuf_Rec://...}}//DisplayClitn的ImgBufQueueImgBufQueue::enqueProvider(ImgBufQueNode const& 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
本文深入解析了CamAdapter与DisplayClient在处理图像缓冲区(Buf)过程中的交互机制,详细阐述了ImgBufQueue、Provider、Buf类及其相互作用。通过展示关键代码片段,解释了如何通过ImgBufQueue进行数据接收与处理,以及CamAdapter如何通过ImgBufProvidersManager管理DisplayClient的图像数据队列。文章进一步讨论了IImgBufProviderClient和IImgBufProvider在数据包管理和提供方面的角色,同时介绍了PreviewBufMgr和ImgBufProvidersManager在数据提取和分发过程中的作用。
869

被折叠的 条评论
为什么被折叠?



