OpenHarmony Camera HDF驱动框架概述
OpenHarmony Camera驱动模型结构
- HDI Implementation:对上实现HDI接口,向下调用框架层的接口,完成HDI接口任务的转发。
- Buffer Manager:屏蔽不同内存管理的差异,为子系统提供统一的操作接口,同时提供buffer轮转的功能。
- Pipeline Core:解析HCS配置完成pipeline的搭建,调度pipeline中的各个node完成流的处理
- Device Manager:通过调用底层硬件适配层接口,实现查询控制底层设备、枚举监听底层设备的功能
- Platform Adaption:屏蔽硬件差异,为Device Manager提供统一的操作底层硬件的能力
CameraService 进程
CameraService源码目录为:foundation/multimedia/camera_standard,camera app通过camera service与hal层进行交互
├── bundle.json
├── figures
├── frameworks camera frameworks部分,支持js和native转换
│ ├── js
│ └── native
├── hisysevent.yaml
├── interfaces CameraService接口
│ ├── inner_api
│ └── kits
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
├── sa_profile CameraService进程加载配置文件
│ ├── 3008.xml
│ └── BUILD.gn
└── services CameraService启动相关
├── camera_service
└── etc
CameraService启动入口在foundation/multimedia/camera_standard/services/etc/camera_service.cfg进行启动配置
"services" : [{
"name" : "camera_service",
"path" : ["/system/bin/sa_main", "/system/profile/camera_service.xml"],
"uid" : "cameraserver",
"gid" : ["system", "shell"],
"secon" : "u:r:camera_service:s0"
}
]
Camera驱动框架介绍
Camera驱动整体架构
camera驱动源码分布
Camera 驱动框架所在的仓为:drivers_peripheral,源码目录为:“drivers/peripheral/camera”。
├── bundle.json
├── figures
│ ├── Camera模块驱动模型.png
│ └── logic-view-of-modules-related-to-this-repository_zh.png
├── hal
│ ├── adapter #平台适配层,适配平台
│ ├── buffer_manager
│ ├── BUILD.gn #Camera驱动框架构建入口
│ ├── camera.gni #定义组件所使用的全局变量
│ ├── device_manager
│ ├── hdi_impl
│ ├── include
│ ├── init #demo sample
│ ├── pipeline_core
│ ├── test #测试代码
│ └── utils
├── hal_c #为海思平台提供专用C接口
│ ├── BUILD.gn
│ ├── camera.gni
│ ├── hdi_cif
│ └── include
├── interfaces #HDI接口
│ ├── hdi_ipc
│ ├── hdi_passthrough
│ ├── include
│ └── metadata
└── README_zh.md
Camera Host HDF驱动
配置文件
Camera Host HDF配置相关在“vendor/kaihong/khdvk_3566b/hdf_config/uhdf/device_info.hcs”
hdi_server :: host {
hostName = "camera_host";
priority = 50;
caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH"];
camera_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
moduleName = "libcamera_hdi_impl.z.so";
serviceName = "camera_service";
}
}
...
}
其中主要参数说明如下:
- hostName = “camera_host”:camera host节点,该节点为一个独立进程,如果需要独立进程,新增属于自己的host节点
- policy = 2:服务发布策略,Camera使用HDI服务,需设置为2
- moduleName:camera host驱动实现库名
- serviceName:服务名称,请保持全局唯一性,后面HDF Manager会根据这个名称拉起camera hdf
camera host服务启动 camera host 服务由hdf_devhost启动,配置文件存放于vendor/etc/init/hdf_devhost.cfg
{
"name" : "camera_host",
"path" : ["/vendor/bin/hdf_devhost", "8", "camera_host"],
"uid" : "camera_host",
"gid" : ["camera_host"],
"caps" : ["DAC_OVERRIDE", "DAC_READ_SEARCH"],
"secon" : "u:r:camera_host:s0"
}
Camera host驱动实现 代码路径:drivers/peripheral/camera/interfaces/hdi_ipc/server/src/camera_host_driver.cpp
驱动入口结构体,后面将该结构体注册进HDF框架中
struct HdfDriverEntry g_cameraHostDriverEntry = {
.moduleVersion = 1,
.moduleName = "camera_service",
.Bind = HdfCameraHostDriverBind,
.Init = HdfCameraHostDriverInit,
.Release = HdfCameraHostDriverRelease,
};
消息发布服务
static int32_t CameraServiceDispatch(struct HdfDeviceIoClient *client, int cmdId,
struct HdfSBuf *data, struct HdfSBuf *reply)
{
HdfCameraService *hdfCameraService = CONTAINER_OF(client->device->service, HdfCameraService, ioservice);
return CameraHostServiceOnRemoteRequest(hdfCameraService->instance, cmdId, data, reply);
}
参数说明:
client:HdfDeviceIoClient设备句柄
cmdId:请求消息命令字
data:其他服务或者IO请求数据
reply:存储返回消息内容数据
绑定服务:初始化设备服务对象和资源对象
int HdfCameraHostDriverBind(HdfDeviceObject *deviceObject)
{
...
hdfCameraService->ioservice.Dispatch = CameraServiceDispatch;
hdfCameraService->ioservice.Open = nullptr;
hdfCameraService->ioservice.Release = nullptr;
hdfCameraService->instance = CameraHostStubInstance();
deviceObject->service = &hdfCameraService->ioservice;
return HDF_SUCCESS;
}
相关说明:
hdfCameraService->ioservice.Dispatch:注册消息分发服务接口
hdfCameraService->instance:创建camerahost实例
驱动初始化函数: 探测并初始化驱动程序
int HdfCameraHostDriverInit(struct HdfDeviceObject *deviceObject)
{
return HDF_SUCCESS;
}
驱动资源释放函数 : 如已经绑定的设备服务对象
void HdfCameraHostDriverRelease(HdfDeviceObject *deviceObject)
{
if (deviceObject == nullptr || deviceObject->service == nullptr) {
HDF_LOGE("%{public}s deviceObject or deviceObject->service is NULL!", __FUNCTION__);
return;
}
HdfCameraService *hdfCameraService = CONTAINER_OF(deviceObject->service, HdfCameraService, ioservice);
if (hdfCameraService == nullptr) {
HDF_LOGE("%{public}s hdfCameraService is NULL!", __FUNCTION__);
return;
}
OsalMemFree(hdfCameraService);
}
设备创建不成功,关闭服务,释放相关资源
DeviceManager
创建SensorManager、FlashManager、ISPManager管理相应的设备。
SensorManager sensor Manager结构如下
class SensorManager : public IManager {
public:
SensorManager();
explicit SensorManager(ManagerId managerId);
virtual ~SensorManager();
RetCode CreateController(ControllerId controllerId, std::string hardwareName);
RetCode DestroyController(ControllerId controllerId, std::string hardwareName);
std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
void Configure(std::shared_ptr<CameraMetadata> meta);
RetCode Start(std::string hardwareName, int buffCont, DeviceFormat& format);
RetCode Stop(std::string hardwareName);
RetCode PowerUp(std::string hardwareName);
RetCode PowerDown(std::string hardwareName);
std::shared_ptr<ISensor> GetSensor(std::string sensorName);
RetCode SendFrameBuffer(std::shared_ptr<FrameSpec> buffer, std::string hardwareName);
void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName);
void SetNodeCallBack(const NodeBufferCb cb, std::string hardwareName);
void SetMetaDataCallBack(const MetaDataCb cb, std::string hardwareName);
private:
bool CheckCameraIdList(std::string hardwareName);
std::vector<std::shared_ptr<SensorController>> sensorList_;
};
}
PowerUp为上电接口,OpenCamera时调用此接口进行设备上电操作
PowerDown为下电接口,CloseCamera时调用此接口进行设备下电操作
Configures为Metadata下发接口,如需设置metadata参数到硬件设备,可实现此接口进行解析及下发
Start为硬件模块使能接口,pipeline中的各个node进行使能的时候,会去调用,可根据需要定义实现,比如sensor的起流操作就可放在此处进行实现,Stop和Start为相反操作,可实现停流操作
SendFrameBuffer为每一帧buffer下发接口,所有和驱动进行buffer交互的操作,都是通过此接口进行的
SetNodeCallBack为pipeline,通过此接口将buffer回调函数设置到devicemanager
SetMetaDataCallBack为metadata回调接口,通过此接口将从底层获取的metadata数据上报给上层
BufferCallback上传每一帧已填充数据buffer的接口,通过此接口将buffer上报给pipeline
SetAbilityMetaDataTag设置需要从底层获取哪些类型的metadata数据,因为框架支持单独获取某一类型或多类型的硬件设备信息,所以可以通过此接口,获取想要的metadata数据
Camera Sensor Controller结构如下:
class SensorController : public IController {
public:
SensorController();
explicit SensorController(std::string hardwareName);
virtual ~SensorController();
RetCode Init();
RetCode PowerUp();
RetCode PowerDown();
RetCode Configure(std::shared_ptr<CameraMetadata> meta);
RetCode Start(int buffCont, DeviceFormat& format);
RetCode Stop();
...
void SetMetaDataCallBack(MetaDataCb cb) override;
void BufferCallback(std::shared_ptr<FrameSpec> buffer);
void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag);
RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta);
RetCode Flush(int32_t streamId);
...
};
PowerUp下发命令给v4l2 dev去操作实际设备进行上电操作 PowerDown下发命令给v4l2 dev去操作实际设备进行下电操作 同理其他操作参考SensorManager. ####FlashManager Flash Manger结构如下:
class FlashManager : public IManager {
public:
FlashManager();
explicit FlashManager(ManagerId managerId);
virtual ~FlashManager();
RetCode CreateController(ControllerId controllerId, std::string hardwareName);
std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
RetCode PowerUp(std::string hardwareName);
RetCode PowerDown(std::string hardwareName);
void Configure(std::shared_ptr<CameraMetadata> meta);
void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName)
{
(void)abilityMetaDataTag;
(void)hardwareName;
return;
}
RetCode SetFlashlight(FlashMode flashMode, bool enable, std::string hardwareName);
private:
bool CheckCameraIdList(std::string hardwareName);
std::vector<std::shared_ptr<FlashController>> flashList_;
}
Flash controller结构如下:
class FlashController : public IController {
public:
FlashController();
explicit FlashController(std::string hardwareName);
virtual ~FlashController();
RetCode Init();
RetCode PowerUp();
RetCode PowerDown();
RetCode Configure(std::shared_ptr<CameraMetadata> meta)
{
(void)meta;
return RC_OK;
}
RetCode SetFlashlight(FlashMode flashMode, bool enable);
void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag);
RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta);
private:
std::mutex startVolock_;
bool startVoState_ = false;
}
ISPManager ISP Manager结构如下
class IspManager : public IManager {
public:
IspManager();
explicit IspManager(ManagerId managerId);
virtual ~IspManager();
RetCode CreateController(ControllerId controllerId, std::string hardwareName);
std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
void Configure(std::shared_ptr<CameraMetadata> meta);
RetCode Start(std::string hardwareName);
RetCode Stop(std::string hardwareName);
RetCode PowerUp(std::string hardwareName);
RetCode PowerDown(std::string hardwareName);
void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName)
{
(void)abilityMetaDataTag;
(void)hardwareName;
return;
}
private:
bool CheckCameraIdList(std::string hardwareName);
std::vector<std::shared_ptr<IspController>> ispList_;
};
ISP controller结构如下
class IspController : public IController {
public:
IspController();
explicit IspController(std::string hardwareName);
virtual ~IspController();
RetCode Init();
RetCode Configure(std::shared_ptr<CameraMetadata> meta);
RetCode PowerUp();
RetCode PowerDown();
RetCode Stop();
RetCode Start();
void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag)
{
(void)abilityMetaDataTag;
return;
}
RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta)
{
(void)meta;
return RC_OK;
}
private:
std::mutex startIsplock_;
bool startIspState_ = false;
}
PlatForm Adapter
这部分通过V4l2框架对video设备进行管理,包括对相应设备的打开、启动/关闭数据流、设置/获取图像格式等等
源代码 V4l2 Adapter 源码位于driver/peripheral/camera/hal/adapter/platform/v4l2/src/driver_adapter 部分关键函数如下:
class HosV4L2Dev {
public:
...
RetCode start(const std::string& cameraID);
RetCode stop(const std::string& cameraID);
RetCode CreatBuffer(const std::string& cameraID, const std::shared_ptr<FrameSpec>&