展锐A13 Camera Hal dispatch模块流程 --- 上

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 &param);
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模块的入口,在接收到数据和请求后,主要是进一步向下调用。让我们期待后面的流程介绍吧。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值