Android架构下 camera驱动开发重要的结构体和流程

一、重要的结构体

//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_resultnotify
*/
(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->initializeconfigure_streamsprocess_capture_requestflush

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。
 

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值