展锐710 Android9 camera hal 框架

本文详细介绍了展锐平台Android9系统中camera HAL层的代码架构,包括SPRD Camera HAL Interface、SPRD Camera OEM及各个关键模块的功能,如sensor、ipm、focus、jpeg_codec等,并探讨了hal层接口的使用,特别是硬件抽象层模块结构体的定义和设备操作方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要介绍展锐平台AndroidP camera hal代码框架,后续会有preview相关流程

1. 代码架构

先来看看主要的代码架构
在这里插入图片描述
app及framework为标准的Android hal3架构

主要涉及的文件及其调用关系如下图:
在这里插入图片描述

Camera HAL 层架构主要由以下几部分构成:

  1. SPRD Camera HAL Interface(SprdCamera3HWI): 实现 camera framework的调用接口。
  2. SPRD Camera OEM(SprdCamera3OEMIf): 连接 camera HWI 与底层。
  3. CMR_OEM:负责 OEM 层的控制以及对底层控制文件的调度

oem 提供了展讯平台 camera 功能的具体实现,包括队列,线程,和状态的相关实现.camera 功能包括 init,deinit,preview,take picture 等;硬件驱动的控制接口;isp 的算法实现,包括 awb,ae 等.包括SprdOEMCamera,cmr_oem,cmr_preview 等文件.

OEM 层的主要文件在 libcamera/oem 目录下。

  • SprdOEMCamera:Camera OEM 模块的接口文件,用来向各种 Camera HAL 层文件提供统一的调用接口。
  • cmr_oem:Camera OEM 模块的控制文件,用来控制其它模块,而其它模块
    的交互也是通过该文件来完成。
  • cmr_sensor:OEM 层 sensor 模块,向其它模块提供 sensor 模块的操作控制接口,处理 sensor 的流程控制。
  • sensor_drv_u :位 于 user 层 sensor 驱动 的抽象接 口文件 ,它直 接操作
    位于 kernel 的 sensor driver,向 cmr_sensor 和位于 user 层的 sensor driver文件提供统一的操作接口。
  • cmr_ipm:OEM 层 ipm 模块,ipm 模块主要是一种图像后处理模块,主要处理第三方的图像处理库,如 Face Detect、 HDR 等等,希望通过本模块实现对外接口的一致,并有利于扩展。
  • cmr_setting:OEM 层 setting 模块,setting 模块主要处理与 Camera HAL层交互的参数,为 Camera OEM 模块提供一组 set/get 函数接口以用来处理相关的 hal 参数。
  • cmr_focus:OEM 层 focus 模块,focus 模块主要处理 AF 的相关操作,并将AF 的结果返回给其它模块。
  • jpeg_codec:OEM 层 jpeg codec 模块的接口文件,该模块为其他模块提供了一组 jpeg 编解码功能的接口文件,用以完成拍照 JPEG 编码的操作。
  • cmr_grab : OEM 层 grab 模 块 , 该 模 块 调 用 sprd image driver 相 关接 口 , 用 来 管 理 DCAM 硬件设备,包含设备通道的配置、 模式的设置、 启动、停止以及数据的读写等功能
  • cmr_scaler:OEM 层 scaler 模块,该模块用来对一帧 buffer 做 scaler 图像后处理操作,管理 scaler 硬件设备。
  • cmr_rotate:OEM 层 rotate 模块,该模块用来对一帧 buffer 做 rotate 图像后处理操作,管理 rotate 硬件设备。
  • cmr_preview:OEM 层 preview 模块,该模块用来为 Camera 提供preview 子服务,包含 preview 流程的控制、 通道参数的配置、 接收 Camera OEM 模块设置的 buffer 给 grab 模块,接收底层返回的 buffer 数据并回调给Camera OEM 模块。
  • cmr_snapshot:OEM 层 snapshot 模块,该模块用来为 Camera 提供拍照后处理操作,它接收图像数据并调用相关模块完成需要的图像后处理及 JPEG编码操作,并生成一个完成的 JPEG 图片返回给 Camera OEM 模块

Driver
主要实现了对 dcam 等硬件功能的实现,具体实现通过中断控制,线程调度.对相关多媒体子系统设置并控制

2. hal层接口

熟悉hal层的应该了解硬件抽象层模块结构体定义规范
相关结构体在 hardware/libhardware/include/hardware/hardware.h 中。


typedef struct hw_module_t {
uint32_t tag; 		//标签必须初始化为HARDWARE_MODULE_TAG
uint16_t module_api_version; //版本号
#define version_major module_api_version //version major
uint16_t hal_api_version;
#define version_minor hal_api_version //version minor
const char *id; //module 的 id
const char *name; //module 的 name
const char *author; // Author\/owner\/implementor of the module( 实现该模块) 
struct hw_module_methods_t\* methods; //模块操作方法void* dso; //module's dso
#ifdef __LP64__
uint64_t reserved[32-7];
#else
uint32_t reserved[32-7]; /** padding to 128 bytes, reserved for future use
*/
#endif
} hw_module_t;

这个结构体使用的时间需要注意的是:
硬件抽象层中的每一个模块都必须自定义一个硬件抽象层模块结构体, 而且它的第一个成员变量的类型必须为 hw_module_t。硬件抽象层中的每一个模块都必须存在一个导出符号HAL_MODULE_INFO_SYM, 即“HWI” , 它指向一个自定义的硬件抽象层模块结构体。
a、 hal_module_info 的名字
#define HAL_MODULE_INFO_SYM HMI
b、 作为一个字符串的 hal_module_info 名称
#define HAL_MODULE_INFO_SYM_AS_STR “HMI”
结构体 hw_module_t 的成员变量 tag 的值必须设置为HARDWARE_MODULE_TAG。 用来标志这是一个硬件抽象层模块结构体。结构体 hw_module_t 的成员变量 dso 用来保存加载硬件抽象层模块后得到的句柄值, 加载硬件抽象层模块的过程实际就是调用 dlopen 函数来加载与其对应的动态链接库文件的过程。 在调用 dlclose 函数来卸载这个这个硬件抽象层模块时, 要用到这个句柄值, 因此, 我们在加载时需要将它保存起来。结构体 hw_module_t 的成员变量 methods 定义了一个硬件抽象层模块的操作方法列表, 它的类型为 hw_module_methods_t,它是用于定义操作设备的方法 operations。 它的定义如下:


typedef struct hw_module_methods_t {
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device); /** Open a specific device( 打开特定的
设备) */
} hw_module_methods_t;
结构体 hw_module_methods_t 只有一个成员变量, 它是一个函数指针, 用来
打开硬件抽象层模块中的硬件设备。 其中 module 表示要打开的硬件设备所在
的模块; 参数 id 表示要打开设备的 id, 参数 device 是一个输出参数, 用来
描述一个已经打开的硬件设备。 由于一个硬件抽象层模块可能会包含多个硬件
设备, 因此, 在调用结构体 hw_module_methods_t 的成员变量 open 来打开
一个硬件设备时, 我们需要指定她的 ID。 硬件抽象层中的硬件设备使用结构
体 hw_device_t 来描述。
typedef struct hw_device_t {
uint32_t tag; //标记 HARDWARE_DEVICE_TAG
uint32_t version; //版本号
struct hw_module_t* module; //该设备( 硬件) 属于哪个 module
#ifdef __LP64__
uint64_t reserved[12]; //预留字段, 将来使用#else
uint32_t reserved[12]; //预留字段, 将来使用
#endif
int (*close)(struct hw_device_t* device); //关闭该设备操作
} hw_device_t;

需要注意的是:
硬件抽象层模块中的每一个硬件设备都必须自定义一个硬件设备结构体, 而且
它的第一个成员变量的类型必须为 hw_device_t。
结构体 hw_device_t 的成员变量 tag 的值必须初始化为HARDWARE_DEVICE_TAG。结构体 hw_device_t 的成员变量 close 是一个函数指针, 它用来关闭一个硬件设备。
camera 的硬件抽象层接口。
位置: hardware/libhardware/include/hardware/camera_common.h


/**
* The id of this module
*/
#define CAMERA_HARDWARE_MODULE_ID "camera"
typedef struct camera_module {
	hw_module_t common;
	int (*get_number_of_cameras)(void);
	int (*get_camera_info)(int camera_id, struct camera_info *info);int (*set_callbacks)(const camera_module_callbacks_t *callbacks);
	void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);
	int (*open_legacy)(const struct hw_module_t* module, const char* id,
	uint32_t halVersion, struct hw_device_t** device);
	int (*set_torch_mode)(const char* camera_id, bool enabled);
	int (*init)();
	void* reserved[5];
} camera_module_t;
位置: hardware/libhardware/include/hardware/camera3
typedef struct camera3_device {
/ * Camera open (common.module->common.methods->open) should
return in */
	hw_device_t common;
	camera3_device_ops_t *ops;
	void *priv;
} camera3_device_t;
定义一个模块操作方法
struct hw_module_methods_t SprdCamera3Factory::mModuleMethods = {
	.open = SprdCamera3Factory::camera_device_open,
};
camera_device_open 会根据传进来的 ID 判断打开哪一个硬件设备。
typedef struct camera3_device_ops {
	int (*initialize)(const struct camera3_device *,const camera3_callback_ops_t *callback_ops);
	int (*configure_streams)(const struct camera3_device *,camera3_stream_configuration_t *stream_list);
	int (*register_stream_buffers)(const struct camera3_device *,const camera3_stream_buffer_set_t *buffer_set);
	int (*process_capture_request)(const struct camera3_device *,camera3_capture_request_t *request);
	void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,vendor_tag_query_ops_t* ops);
	void (*dump)(const struct camera3_device *, int fd);
	int (*flush)(const struct camera3_device *);
	/* reserved for future use */
	void *reserved[8];
}camera3_device_ops_t;

在经过上面的方法之后得到 camera3_device_ops_t , 上层会调用其中的initialize, 把 framework 层的回调函数 camera3_callback_ops_t 传至底层,底层获取数据时调用里面的两个方法。 这个调用在每次执行一个新的操作的时间会执行一次, 比如开始的时间是正常的 preview, 然后切换到 video,着时间就会调用这个方法;然后上层会调用 configure_streams 方法, 配置流, 因为每种操作所需要的参数可能都是不同的, 所以这个方法在每执行一个动作的时间都会调用;最后就是调用 process_capture_request 去将数据下发并开始动作;所以总结下来 framework 对 hal 层进行操作过程可以简单的理解为initialize->configure_streams-> process_capture_request。


typedef struct camera3_callback_ops {
	void (*process_capture_result)(const struct camera3_callback_ops *,
	const camera3_capture_result_t *result);
	void (*notify)(const struct camera3_callback_ops *,
	const camera3_notify_msg_t *msg);
}camera3_callback_ops_t;
下面是 ops 所对应的方法。
camera3_device_ops_t SprdCamera3HWI::mCameraOps = {
	initialize: SprdCamera3HWI::initialize,
	configure_streams: SprdCamera3HWI::configure_streams,
	register_stream_buffers:	NULL,//SprdCamera3HWI::register_stream_buffers,
	construct_default_request_settings:SprdCamera3HWI::construct_default_request_settings,
	process_capture_request:
	SprdCamera3HWI::process_capture_request,
	get_metadata_vendor_tag_ops:
	NULL,//SprdCamera3HWI::get_metadata_vendor_tag_ops,
	dump: SprdCamera3HWI::dump,
	flush: SprdCamera3HWI::flush,reserved:{0},
};

SprdCamera3Hal.cpp 是 hal 层提供给 framework 的接口。
camera_module_t HAL_MODULE_INFO_SYM = {
	common: camera_common,
	get_number_of_cameras: sprdcamera::SprdCamera3Factory::get_number_of_cameras,
	get_camera_info: sprdcamera::SprdCamera3Factory::get_camera_info,
	set_callbacks: sprdcamera::SprdCamera3Factory::set_callbacks,/*HAL3.2*/
	get_vendor_tag_ops:	sprdcamera::SprdCamera3Factory::get_vendor_tag_ops,/*HAL 3.2 主
	要是将 setting 里面的数据回传*/
	open_legacy :0,/*HAL1.0*/
	set_torch_mode: sprdcamera::SprdCamera3Factory::setTorchMode,
};
static hw_module_t camera_common = {
	tag: HARDWARE_MODULE_TAG,
	module_api_version:	CAMERA_MODULE_API_VERSION_2_4,//CAMERA_MODULE_API_VERSION_2_0,
	hal_api_version: HARDWARE_HAL_API_VERSION,
	id: CAMERA_HARDWARE_MODULE_ID,
	name: "Sprd Camera HAL3",
	author: "Spreadtrum Corporation",
	methods: &sprdcamera::SprdCamera3Factory::mModuleMethods,
	dso: NULL,
	reserved: {0},
};

在 frameworks/av/services/camera/libcameraservice 下面的
CameraService.cpp 里面。

 void CameraService::onFirstRef()
{
	camera_module_t *rawModule; //定义这个模块的指针对象
	int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,	(const hw_module_t **)&rawModule); //获得这个模块的 ID, 在上面的结构体可以看到, 在 HAL 层里面的 ID 就是这个。 通过 hw_get_module这个函数也就获取到了 HAL 层的接口。
	mModule = new CameraModule(rawModule); //获得这个模块里面的方法
	err = mModule->init();
} 然后调用 hardware/libhardware 下面的 hardware.c 里面的 hw_get_module方法。

int hw_get_module(const char *id, const struct hw_module_t **module)
{
	return hw_get_module_by_class(id, NULL, module);
} 
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
	return load(class_id, path, module);
} 
Load 应该就会获取下面这个结构体里面的 ID。 这个是在 HAL 层里面的。
static hw_module_t camera_common = {
	tag: HARDWARE_MODULE_TAG,
	id: CAMERA_HARDWARE_MODULE_ID,
	methods: &sprdcamera::SprdCamera3Factory::mModuleMethods,
};
struct hw_module_methods_t SprdCamera3Factory::mModuleMethods = {
	open: SprdCamera3Factory::camera_device_open,
}; 然后就可以开始执行 HAL 层的 opencamera 和 request 的下发。
### IDispatch 架构介绍 平台的IDispatch架构主要用于优化图像信号处理器(ISP)的效果调优和支持不同ISP版本之间的兼容性[^1]。该架构设计旨在提供一种高效的方法来管理和调整ISP中的各个功能模块,从而确保摄像头系统的性能达到最优。 #### 特点概述 - **统一接口层**:通过定义一组标准APIs, IDisatch允许应用程序开发者无需关心底层硬件细节即可访问并控制ISP的各项特性。 - **跨代兼容性**:为了适应不断演进的技术需求以及新旧产品线间的平滑过渡,此框架特别注重保持向后的兼容能力,使得基于早期版本开发的应用程序能够在新一代设备上继续运行良好而不必重新编写大量代码。 - **灵活配置管理**:提供了强大的工具集用于创建、编辑和保存特定场景下的最佳设置组合——即所谓的“Tuning Profile”。这些预设可以被迅速加载到目标平台上以实现实时视觉效果增强或修正已知缺陷等问题。 - **高效的参数生成与打包机制**:借助于专门设计的数据结构和算法模型,能够自动生成适用于多种应用场景的最佳参数集合,并将其封装成易于分发的形式供后续使用。 ```python def generate_tuning_profile(isp_version, scene_type): """ Generates a tuning profile based on the ISP version and specific scene type. Args: isp_version (str): Version of the ISP to tune for. scene_type (str): Type of scene being captured. Returns: dict: Tuning parameters optimized for given conditions. """ # Placeholder implementation; actual logic would involve complex calculations return { "exposure": calculate_exposure(scene_type), "white_balance": adjust_white_balance(isp_version), "color_matrix": apply_color_correction() } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

autho

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值