一、重要的结构体
//hardware/libhardware/include/hardware/camera3.h
(1)
typed enum camera3_stream_type{
CAMERA3_STREAM_OUTPUT = 0,//输出流;camera HAL设备将用新捕获或重新处理的图像数据填充到输出流中的缓冲区。
CAMERA3_STREAM_INPUT = 1, //输入流;cameraHAL设备将从输入流中缓冲区读取并将它们发送给camera的pipeline处理
CAMERA3_STREAM_BIDIRECTIONAL = 2, //流可用于输入和输出; 输出流多。流通常用于零快门延迟(ZSL)特性
}camera3_stream_type_t
/*
指向单个摄像机输入或输出流的句柄,framework根据其缓冲区分辨率和格式定义流,HAL的gralloc使用标志和最大缓冲区计数。
*/
(2)
typedef struct camera3_stream {
int stream_type; //流的格式,输入流还是输出流。framework在configure_streams()之前设置
uint32_t width; //缓冲区的宽
uint32_t height; //缓冲区的高
int format; //流中缓冲区的像素格式
uint32_t usage; //流gralloc的使用标志。configure_streams()设置。HAL消费输入流,HAL生产输出流。输入流和输出流的使用标志结合在一起,发给galloc HAL模块,然后为每个流分配缓冲区
uint32_t max_buffers; //退出队列的最大缓冲区数
void *priv; //流的HAL层私有信息的句柄
android_dataspace_t data_space; //描述缓冲区内容的字段,定义了缓冲区内数据的含义。对于大多数格式,数据空间定义图像数据的颜色空间。
int rotation; //流需要输出旋转方向
const char* physical_camera_id; //此流所属的物理摄像机id
}camera3_stream_t
/*
configure_streams()使用的流结构。该结构定义当前usecase 的输出流和再处理输入流的结构
*/
(3)
typedef struct camera3_stream_configuration {
uint32_t num_streams; //framework下发的输入和输出流,至少有一个output-capable流
camera3_stream_t **streams;
uint32_t operation_mode; //流的操作模式
const camera_metadata_t *session_parameters;
}camera3_stream_configuration_t
/*
framework调用process_capture_request给HAL设备的拍照请求/buffer再处理
request包含用于此capture的设置,以及一组用于写入结果图像数据的输出缓冲区
capture由frame_number标识。
*/
(4)
typedef struct camera3_capture_request {
uint32_t frame_number; //framework设置帧号
const camera_metadata_t *settings //请求中包含capture和处理参数的设置buffer
uint32_t num_output_buffers;
const camera3_stream_buffer_t *output_buffers;
uint32_t num_physcam_settings;
const char **physcam_id;
const camera_metadata_t **physcam_settings;
}camera3_capture_request_t
/*
相机HAL设备一次capture/再处理的结果。这是通过process_capture_result()异步发送给framework的,以响应使用process_capture_request()发送给HAL的单个capture请求。
一个request请求可以有多个result来返回。每个调用,都有相同的帧number,每个帧有固定的元数据
*/
(5)
typedef struct camera3_capture_result {
uint32_t frame_number;
const camera_metadata_t *result; //此捕获的结果元数据。最终捕获参数,捕获状态和后处理硬件,3A算法的状态,只有一个给定帧号的process_capture_result()调用可以包含结果元数据。对相同frame_number的所有其他调用必须设置为NULL。
uint32_t num_output_buffers;
const camera3_stream_buffer_t *output_buffers;
const camera3_stream_buffer_t *input_buffer;
uint32_t partial_result;
uint32_t num_physcam_metadata;
const char **physcam_ids;
const camera_metadata_t **physcam_metadata;
}camera3_capture_result_t
/*
HAL-->framework
camera3_callback_ops->process_capture_result、notify
*/
(6)
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); //HAL发给framework的错误或异步回调(shuuter事件(帧号和开始曝光的时间戳))
camera3_buffer_request_status_t (*request_stream_buffers)(
const struct camera3_callback_ops *,
uint32_t num_buffer_reqs,
const camera3_buffer_request_t *buffer_reqs,
/*out*/uint32_t *num_returned_buf_reqs,
/*out*/camera3_stream_buffer_ret_t *returned_buf_reqs);
void (*return_stream_buffers)(
const struct camera3_callback_ops *,
uint32_t num_buffers,
const camera3_stream_buffer_t* const* buffers);
}camera3_callback_ops_t
/*
framekwork->HAL
camera_module->common.open
camera3_device_ops->initialize、configure_streams、process_capture_request、flush
camera3_device_t->common.close
*/
(7)
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 *, //重置HAL摄像机设备处理管道,并设置新的输入和输出流
camera3_stream_configuration_t *stream_list);
int (*register_stream_buffers)(const struct camera3_device *,
const camera3_stream_buffer_set_t *buffer_set);
const camera_metadata_t* (*construct_default_request_settings)(
const struct camera3_device *,
int type);
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 *);
void (*signal_stream_flush)(const struct camera3_device*,
uint32_t num_streams,
const camera3_stream_t* const* streams);
int (*is_reconfiguration_required)(const struct camera3_device*,
const camera_metadata_t* old_session_params,
const camera_metadata_t* new_session_params);
}camera3_device_ops_t
//hardware/libhardware/include/hardware/camera_common.h
(8)
typedef struct camera_module {
hw_module_t common; //摄像头模块的常用方法。 *必须*是camera_module,因为此结构的用户会将hw_module_t投射到在已知hw_module_t的上下文中的camera_module指针引用camera_module。
//camera_module的common.methods-> open的返回值为:0:成功打开照相机设备时。
int (*get_number_of_cameras)(void); //返回可通过摄像机访问的摄像机设备的数量 模块。 摄像头设备编号为0到N-1,其中N为此调用返回的值。
//open()的摄像头设备名称只是将数字转换为字符串。 也就是说,相机ID 0为“ 0”,相机ID 1为“ 1”。
int (*get_camera_info)(int camera_id, struct camera_info *info); //返回给定相机设备的静态相机信息。 这个相机设备的信息可能不会更改。
int (*set_callbacks)(const camera_module_callbacks_t *callbacks); //提供指向HAL模块的回调函数指针,以告知异步相机模块事件框架。 在初始摄像机HAL模块加载之后
//首次调用get_number_of_cameras()方法之后以及对该模块进行任何其他调用之前,该框架将调用此函数一次。
void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops); //获取查询供应商扩展元数据标签信息的方法。 HAL应该填写所有供应商标签操作方法,
//或者如果未定义供应商标签,则保持ops不变。
int (*open_legacy)(const struct hw_module_t* module, const char* id,
uint32_t halVersion, struct hw_device_t** device); // 对于多个Hal API版本,直选一个,一般不用低版本的。返回值:0:成功打开摄像头设备。
int (*set_torch_mode)(const char* camera_id, bool enabled); //打开或关闭与给定关联的闪光灯的手电筒模式相机ID。
//1、如果操作成功,则HAL必须通过调用具有新状态的camera_module_callbacks.torch_mode_status_change()来通知framework火炬状态。
//2、摄像机设备具有更高的优先级访问闪光灯。 当存在任何资源冲突时,例如调用open()打开摄像头设备时,HAL模块必须通过
//camera_module_callbacks.torch_mode_status_change()通知framework,火炬模式已关闭并且火炬模式状态已变为TORCH_MODE_STATUS_NOT_AVAILABLE。
//3、当打开手电筒模式的资源再次可用时,HAL模块必须通过以下方式通知framework camera_module_callbacks.torch_mode_status_change()
//表示要调用set_torch_mode()时,火炬模式状态已变为TORCH_MODE_STATUS_AVAILABLE_OFF
//4、 当framework调用set_torch_mode()打开闪光灯的手电筒模式时,如果HAL无法同时打开多个手电筒模式,则HAL应该关闭由先前的set_torch_mode()
//调用打开的手电筒模式,并通知framework该闪光灯组件的手电筒模式状态已变为TORCH_MODE_STATUS_AVAILABLE_OFF。
int (*init)(); //在成功调用Camera HAL库之后,Camera Service将在调用任何其他方法之前调用此方法。 如果不需要初始化,则HAL模块可以将其保留为NULL.HAL实现可以将其用于执行初始化和其他一次性操作。
void* reserved[5]; //保留以备将来使用
} camera_module_t;
//hardware/libhardware/include/hardware/hardware.h
(9)
typedef struct hw_module_t {
uint32_t tag;
uint16_t module_api_version;
uint16_t hal_api_version;
const char *id;
const char *name;
const char *author;
struct hw_module_methods_t* methods;
void* dso;
#ifdef __LP64__
uint64_t reserved[32-7];
#else
uint32_t reserved[32-7];
#endif} hw_module_t;
(10)
typedef struct hw_module_methods_t {
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);} hw_module_methods_t;
//hardware/libhardware/include/hardware/camera3.h
(11)
typedef struct camera3_device {
hw_device_t common;
camera3_device_ops_t *ops;
void *priv;
}camera3_device_t
//hardware/libhardware/include/hardware/hardware.h
(12)
typedef struct hw_device_t {
uint32_t tag;
uint32_t version; //特定于模块的设备API的版本。
struct hw_module_t* module;
uint64_t reserved[12];#else
uint32_t reserved[12];#endif
int (*close)(struct hw_device_t* device);
} hw_device_t;
二、camera启动和一般预期的操作顺序:
1、打开相机:framework调用结构体camera_module这块的common方法,camera_module_t-> common.open(),在结构体hw_module_methods_t这块的open你的方法来打开特定 Camera,返回一个结构体的 hardware_device_t结构。
2、检查设备硬件版本,并为之实例化:framework检查结构体hardware_device_t-> version字段,并为该版本的相机硬件设备实例化适当的处理程序。 如果版本为CAMERA_DEVICE_API_VERSION_3_0,则设备将投射到结构体的camera3_device_t。
3、初始化:在open()之后,ops结构中的任何其他函数之前,只调用一次initialize。framework使用framework回调函数指针调用结构体3.1camera3_device_t-> ops->结构体3.2camera3_device_ops的 initialize()。
4、配流:framework调用结构体camera_device方法ops调用结构体camera3_device_ops的configure_streams方法配流,camera3_device_t-> ops-> configure_streams(),并把input stream&output stream 的列表作为参数送到Hal层。
5、注册流buffer:API3.1->framework分配gralloc buffer和在configure_streams中,调用结构体3.1camera_device方法ops调用结构体3.2camera3_device_ops的register_stream_buffers方法注册stream buffer,camera3_device_t-> ops-> register_stream_buffers()至少有一个输出流。 同一流仅注册一次。API3.2-> 没有调用camera3_device_t-> ops-> register_stream_buffers(),并且必须为NULL。
6、配置默认请求:可能在步骤3之后的任何时间发生,framework通过调用结构体camera_device方法ops调用结构体camera3_device_ops的construct_default_request_settings方法配置默认请求,camera3_device_t-> ops-> construct_default_request_settings。
7、下发Capture请求:在使用默认设置中的一组设置和至少一个输出流(已由Framework较早注册),framework构造并向HAL发送第一个捕获请求。
framework调用 结构体3.1camera_device方法ops调用结构体camera3_device_ops的process_capture_request开始下发request请求,通过camera3_device_t-> ops-> process_capture_request()发送到HAL。 在准备好发送下一个request前,HAL必须返回此调用。 API3.2->
在camera3_capture_request_t的camera3_stream_buffer_t数组中提供的buffer_handle_t可能是新的,而且在任意给的request中,HAL层都没见这个buffer_handle_t。
8、获取其他use case:framework继续提交请求,并调用Construct_default_request_settings获取默认设置缓冲区其他use cases。API3.1->framework此时可以调用 register_stream_buffers()来尚未注册的流。
9、通知&处理Capture请求:在开始捕获请求时(Sensor开始暴露于 Capture)或者开始处理重处理请求时,HAL使用SHUTTER事件和包括帧号和开始曝光的时间戳,调用结构体3.3camera3_callback_ops_t-> notify()。 对于重新处理请求,时间戳必须是输入图像曝光的开始,当调用process_capture_request()后,查看时间戳在camera3_capture_request_t.settings中android.sensor.timestamp。
API3.1-> 对于同帧率来说,来自Hal的结构体3.3camera3_callback_ops的notify()方法必须在 process_capture_result()之前调用
API3.2-> 对于带有SHUTTER事件的camera3_callback_ops_t-> notify()应该尽快调用,因为framework具有有效的时间戳记以开始曝光( 或针对重新处理请求的输入图像的曝光开始)才能将为应用程序层(针对该帧)传递gralloc缓冲区。在SHUTTER事件之前或之后的任何时间,部分元数据结果和gralloc缓冲区都可以发送到framework。
10、上传处理result:经过一些pipeline延迟之后,HAL开始使用结构体3.3camera3_callback_ops返回处理后Capture给framewrok, camera3_callback_ops_t->process_capture_result()。返回的顺序与提交请求的顺序相同。根据camera HAL设备的pipeline深度,可以同时处理多个request。
API3.2->
(1)一旦process_capture_result返回buffer作为camera3_stream_buffer_t数组,release_fence指定的栅已经被触发(这是-1栅的无操作),该buffer的所有权被认为已转移回framework。之后,HAL必须不再保留该特定buffer,并且framework可以立即为其清除内存。(2)对于单个帧, 每次带有新的不相交的元数据和或一套gralloc buffer,可以多次调用process_capture_result. (3)framework会将这些部分元数据result合并为一个result。 特别是,只要上述规则对于gralloc buffer(输入和输出)均成立,则同时为帧N和帧N + 1调用process_capture_result是合法的。11、停流操作:一段时间后,framework可能会停止提交新请求,等待现有捕获完()结束camera session。 当没有其他来自framework的调用处于活动状态时,可以随时调用此方法。,尽管所有正在进行的Capture(返回所有结果,填充所有缓冲区)结束前都会阻塞。 close调用返回后,HAL将不再允许调用结构体3.3camera3_callback_ops_t函数。 一旦进行close()调用,framework就不能调用任何其他HAL设备功能。
13、出现错误&异常:(1)如果发生错误或其他异步事件,则HAL必须调用结构体3.3camera3_callback_ops_t-> notify()具有相应的错误/事件()之外的方法应返回-ENODEV或NULL。