4月份就知道展锐A13的Camera Hal有大的变动,但是最近一直在做一个MTK的项目,没去看这个新增部分的流程。最近有时间,就把A13上Camera Hal新增的部分流程捋 了一下,过程是痛苦的,但是坚持一遍遍去读代码,在结合展锐的官方文档,思路就慢慢清晰了。
整个hal总共新增了两个模块,dispatch 和 lwp,我们先看dispatch模块,在看lwp模块,最后就可以将两个模块的流程串起来。
本篇文章先来说这几个文件,路径在: vendor\sprd\modules\libcamera\hal3_2v6\dispatch
FrameDispatch
FrameDispatch.h
1,DispatchFrameInfo :就是camera_frame_type 的一个封装
FrameDisaptch.h 内部有4个类(这里说的类包括类和结构体哈)
typedef struct DispatchFrameInfo {
DispatchFrameInfo () {
memset(&queue_frame, 0, sizeof(struct camera_frame_type));
FrameTrace = PROCESS;
}
enum trend {
INVAIL,
PROCESS,
PAUSED,
INGNAL,
} FrameTrace;
struct camera_frame_type queue_frame;
} DispatchFrameInfo_t;
2,Framelisten
Framelisten 里面有个枚举 policy_listen_type_t,共9个类型,就对对应9个framePolicy。我们后面会看到这个Framelisten经常出现的。
注意区分 listen_type_t 和 policy_listen_type_t
class Framelisten {
public:
typedef enum { LISTEN_LWP, LISTEN_HAL, LISTEN_REPROCESS, LISTEN_BPC, LISTEN_YUV, LISTEN_MAX } listen_type_t;
typedef enum {
POLICY_LISTEN_MIN = 0,
POLICY_LISTEN_NORMALSINGLE_STREAMING = 1 << 0,//1
POLICY_LISTEN_NORMALSINGLE_CAPTURE = 1 << 1,//2
POLICY_LISTEN_MULTIFRAME_CAPTURE = 1 << 2,//4
POLICY_LISTEN_RAWFRAME_CAPTURE = 1 << 3,//8
POLICY_LISTEN_NOZSL_CAPTURE = 1 << 4,//16
POLICY_LISTEN_FRAME_BUF_SWAP = 1 << 5,//32
POLICY_LISTEN_RAWFRAME_SINGLE_CAPTURE = 1 << 6,//64
POLICY_LISTEN_CAPTURE_BASE = 1 << 7,//128
POLICY_LISTEN_CAPTURE_PTC = 1 << 8,//256
POLICY_LISTEN_MAX = 1<<30,
} policy_listen_type_t;
Framelisten(policy_listen_type_t id) : policyTypeId(id){};
virtual ~Framelisten() = default;
/**
* Listen for frames being processed
*/
virtual void setCameraIf(SprdCamera3OEMIf *oem){};
virtual int32_t onFrameAvailable(std::shared_ptr<DispatchFrameInfo_t> frame) = 0;
policy_listen_type_t policyTypeId;
vector<camera_frame_type> inputdataVec;
};
3,FrameProducer
FrameDispatch中就定了3个函数,它的实现类是FrameProcesser.cpp
virtual int32_t waitForNextFrame(nsecs_t timeout) { return 0; };
virtual int32_t popOneBuffer(std::shared_ptr<DispatchFrameInfo_t>) { return 0; };
virtual CameraFrameDispatch::Framelisten::policy_listen_type_t getListenTypeByResult(std::shared_ptr<DispatchFrameInfo_t> frame) = 0;
4,RangeListener
RangeListener就像一个demo类,主要就是这连个数据成员组装到一起
struct RangeListener {
CameraFrameDispatch::Framelisten::policy_listen_type_t typeId;
weak_ptr<Framelisten> listener;
};
关键数据成员和函数:
weak_ptr<FrameProducer> mProducer;
List<RangeListener> mRangeListeners;
int32_t registerListener(CameraFrameDispatch::Framelisten::policy_listen_type_t typeId,const std::shared_ptr<Framelisten> &listener);
int32_t removeListener(CameraFrameDispatch::Framelisten::policy_listen_type_t typeId,std::shared_ptr<Framelisten> &listener);
virtual bool threadLoop();
void processFrames(std::shared_ptr<FrameProducer> &producer);
int32_t processListeners(std::shared_ptr<DispatchFrameInfo_t> frame,const std::shared_ptr<FrameProducer> &producer);
再来看FrameDispatch.cpp文件实现
FrameDispatch.cpp:
1,registerListener 与 removeListener
就是维护了 List mRangeListeners; 数据成员
int32_t CameraFrameDispatch::registerListener(
Framelisten::policy_listen_type_t typeId, const std::shared_ptr<Framelisten> &listener) {
// Mutex::Autolock l(mInputMutex);
List<RangeListener>::iterator item = mRangeListeners.begin();
while (item != mRangeListeners.end()) {
if (item->typeId == typeId && item->listener.lock() == listener) {
LOGD("Attempt to register the same client twice, ignoring, typeId %d", typeId);
return LWP_SUCCESS;
}
item++;
}
RangeListener rListener = {typeId, listener};
mRangeListeners.push_back(rListener);
LOGI("policy::%d, mRangeListeners size %d", typeId, mRangeListeners.size());
return LWP_SUCCESS;
}
int32_t CameraFrameDispatch::removeListener(Framelisten::policy_listen_type_t typeId,
std::shared_ptr<Framelisten> &listener) {
Mutex::Autolock l(mInputMutex);
List<RangeListener>::iterator item = mRangeListeners.begin();
while (item != mRangeListeners.end()) {
if (item->typeId == typeId && item->listener.lock() == listener) {
item = mRangeListeners.erase(item);
} else {
item++;
}
}
LOGI("policy %d, mRangeListeners size %d", typeId, mRangeListeners.size());
return LWP_SUCCESS;
}
2,threadLoop
threadLoop 的流程绘制了如下流程图:ThreadLoop最终是要调用Framelisten的 onFrameAvailable
FrameProcesser
FrameProcesser.h
class cameraFrameProducer : public CameraFrameDispatch::FrameProducer
这个就是实现了我们上面说的CameraDispatch.h中定义的FrameProducer。不知道为什么要这样取名字,类名叫Producer,文件名却叫Processer。
.h 文件就是声明数据成员和函数成员,没有结构体和内部类
关键数据成员:
map<result_list_type, list<struct camera_frame_type *>> mFrameDataMap;
vector<shared_ptr<CameraFrameDispatch::Framelisten>> mListen;
vector<stream_t> __stream_list;
关键函数成员:
ps系列:
void setPsOps(lwp_ops_t *ops);
void setPsHandle(cmr_u32 camera_id, void *oem_handle, void *prev_handle,
void *snp_handle, void *sns_handle, void *setting_handle,
void *grab_handle, void *isp_handle);
void clearPsHandle(cmr_u32 camera_id);
buffer系列:
virtual int32_t waitForNextFrame(nsecs_t timeout);
virtual int32_t popOneBuffer(std::shared_ptr<DispatchFrameInfo_t> frame);
virtual void pushBufferQueue(struct camera_frame_type *frame);
void requestBuffer(struct camera_frame_type *tmp_data) { return; }
int restoreBuffer(struct camera_frame_type *tmp_data) { return 0; }
stream系列:
void clearStream();
void addStream(stream_t stream, int32_t is_first_configure = 0);
生命周期相关系列:
bool producerInit(int32_t lwp_session);
bool producerStart(dispatch_cb cb = nullptr);
bool producerStop(dispatch_cb cb = nullptr);
other:
virtual policy_listen_type_t getListenTypeByResult(std::shared_ptr<DispatchFrameInfo_t> frame);
FrameProcesser.cpp
1,构造函数
- clearResources
- 清 AdapterRef
- CtreatePolicyMgrInstance
cameraFrameProducer::cameraFrameProducer(SprdCamera3OEMIf *parent)
: mPolicyMgr(nullptr), mOEMIf(parent), status(STATE_MIN) {
clearResources();
auto it = find_if(
AdapterRef.begin(), AdapterRef.end(),
[&](uint32_t adap) {
return parent->mCameraId == adap;
});
if (it != AdapterRef.end()) {
AdapterRef.erase(it);
};
std::unique_lock<std::mutex> l(mProducerLock);
mPolicyMgr = FramePolicyMgr::CtreatePolicyMgrInstance();
LOGD("Initialize cameraFrameProducer, mPolicyMgr %p", mPolicyMgr);
}
2,析构函数
- clearResources
- 清 AdapterRef
- sessionAdapter的stop & delete & MsgBus
- DestoryPolicyMgrInstance
cameraFrameProducer::~cameraFrameProducer() {
clearResources();
std::unique_lock<std::mutex> l(mProducerLock);
{
std::unique_lock<std::mutex> l(mAdapterRefLock);
auto it = find_if(
AdapterRef.begin(), AdapterRef.end(),
[&](uint32_t adap) {
return mOEMIf->mCameraId == adap;
});
if (it != AdapterRef.end()) {
AdapterRef.erase(it);
// AdapterRef.push_back(parent->mCameraId);
};
if (!AdapterRef.size() && sessionAdapter) {
sessionAdapter->stop(nullptr);
delete sessionAdapter;
sessionAdapter = nullptr;
gLwpMsgBus.removeAllListeners();
}
}
if (mPolicyMgr) mPolicyMgr->DestoryPolicyMgrInstance();
mPolicyMgr = nullptr;
LOGD("Destory cameraFrameProducer, mPolicyMgr Object");
};
3,clearResource
清两个关键成员:mFrameDataMap 和 mListen
bool cameraFrameProducer::clearResources() {
std::unique_lock<std::mutex> l(mProducerLock);
for(auto & frameData:mFrameDataMap) {
list<camera_frame_type *>::iterator item = frameData.second.begin();
while (item != frameData.second.end()) {
free(*item);
item = frameData.second.erase(item);
}
}
for(auto &l:mListen) {
l->inputdataVec.clear();
}
return true;
}
4,ps系列
都是转到 sessionAdapter 中
void cameraFrameProducer::setPsOps(lwp_ops_t *ops) {
if (sessionAdapter) {
sessionAdapter->setPsOps(ops);
} else {
LOGE("sessionAdapter is NULL");
}
}
void cameraFrameProducer::setPsHandle(cmr_u32 camera_id, void *oem_handle,
void *prev_handle, void *snp_handle,
void *sns_handle, void *setting_handle,
void *grab_handle, void *isp_handle) {
if (sessionAdapter) {
mOEM = (struct camera_context *)oem_handle;
sessionAdapter->setPsHandle(camera_id, oem_handle, prev_handle, snp_handle,
sns_handle, setting_handle, grab_handle,
isp_handle);
} else {
LOGE("sessionAdapter is NULL");
}
}
5,stream系列
维护 __stream_list 集合
void cameraFrameProducer::clearStream() {
LOGI("clear all stream");
for (auto it = __stream_list.begin(); it != __stream_list.end();) {
it = __stream_list.erase(it);
}
}
void cameraFrameProducer::addStream(stream_t stream, int32_t is_first_configure) {
auto it = find_if(
__stream_list.begin(), __stream_list.end(), [&](const stream_t &sl) {
return (sl.width == stream.width) && (sl.height == stream.height) &&
(sl.format == stream.format);
});
if (it == __stream_list.end())
__stream_list.push_back(stream);
LOGI("stream_fmt %d, stream_size %dx%d, stream_list %d",
stream.format, stream.width,
stream.height, __stream_list.size());
}
6,生命周期系列:producerInit、producerStart、producerStop
sessionAdapter 是Lwp模块的内容,我们后续文章会讲解
producerStart 关键逻辑
producerStop 的关键代码:
7,pushBufferQueue 和 popOneBuffer
主要就是维护了 map<result_list_type, list<struct camera_frame_type *>> mFrameDataMap;
8,委托给PolicyMgr处理的函数
总结下:cameraFrameProducer 主要是作为一个中间过程,将参数数据转给 sessionAdapter 和 PolicyMgr。需要注意其与生命周期相关的三个函数,这三个函数的调用与Camera的open和预览流程相关。
FramePolicyMgr
FramePolicyMgr.h
1,模板类:ThreadJobQueue
主要是维护了一个 std::queue<JobQue_T> mQueue; insert、pop等
template <typename JobQue_T> class ThreadJobQueue
2,结构体及指针函数
3,policyFrameThread
这个内部类的内容很短,是个Thread类型,关键点是在其loop中调用FramePolicy类型的 startThread
4,模板类 FramePolicy ,继承自FramePolicyBase
其中包含一个数据成员是 policyFrameThread
template <typename JobQue_T> class FramePolicy : public FramePolicyBase
关键成员:
ThreadJobQueue<JobQue_T> mThreadQueue;
sp<policyFrameThread> mListenThread;
mThreadQueue 就是一个queue,用来装数据的一个集合:
void enqueThreadJob(JobQue_T value) {
return mThreadQueue.InsertQue(value);
};
bool clearThreadJob() {
return mThreadQueue.Clear();
};
bool dequeThreadJob(JobQue_T &value) {
return mThreadQueue.PopQue(value);
};
5,FramePolicyMgr的声明
关键数据成员
std::map<policy_listen_type_t, sp<FramePolicyBase>> mPolicyTabelMap;
std::map<uint32_t, uint32_t> snapReq_list;
std::map<uint32_t, std::shared_ptr<request_info_t>> mRequestInfo;
MsgNotifier<bufferFd, Buffer *> requestCompleted;
void *sHandler[20];
关键函数:
match系列:
policy_listen_type_t matchPolicy(std::shared_ptr<DispatchFrameInfo_t> frame);
policy_listen_type_t matchPolicy(dispatch_request_info &Req); //*request info*/
构造与析构:
static FramePolicyMgr *CtreatePolicyMgrInstance();
void DestoryPolicyMgrInstance();
Buffer系列:
int32_t request(dispatch_request_info &Req);
void qRequestParams(request_info_t ¶m);
void dqRequestParams(uint32_t frame_num);
int32_t returnZslBuffer(int32_t frame_fd);
void clearBufferList();
回调:
int32_t onLwpDataArrivedListener(PipeLineType &type,Buffer *buffer, void *priv);
policyLoad:
int32_t policyModulesLoad();
void policyModulesLoadSelf();
好多函数在上一节介绍 cameraFrameProducer 的时候提到过,是从 cameraFrameProducer 调过来的。
FramePolicyMgr.cpp
1,内部类:class preLoaderPolicy
遍历:static const char *policy_modules_path = “/odm/lib/lwpPolicy”; 路径下的so文件
将读到的so中的handler转到 mHandler中
find lib path的log打印
2,FramePolicyMgr 的构造与析构
构造函数:
memset(sHandler, 0, sizeof(sHandler));
析构函数主要做一些资源的释放工作
3,match 系列
math就是遍历 mPolicyMap中所有policy的match。
request 和 returnZslBuffer 也是同样的道理
4,mRequestInfo 集合数据的维护
5,FramePolicyMgr::policyModulesLoadSelf
遍历所有Policy的so文件,和上面 class preLoaderPolicy 的流程是一样的
6,FramePolicyMgr::policyModulesLoad
先看下 preLoaderPolicy 有没有正常加载了Policy,没有的话,就调用自己的 policyModulesLoadSelf 加载。
7,FramePolicyMgr::policyModulesLoad
实例化so库的各个policy,并将其装入到 mPolicyTabelMap 中
总结下 FramePolicyMgr.cpp,主要是加载9个so库中的policy,将其装入到 std::map<policy_listen_type_t, sp> mPolicyTabelMap;
然后在各个函数调用中把请求转到对应的policy中去处理。
本篇文章主要介绍三个cpp文件:FrameDispatch.cpp、FrameProcesser.cpp、FramePolicyMgr.cpp。作为dispatch模块的入口,在接收到数据和请求后,主要是进一步向下调用。让我们期待后面的流程介绍吧。