camera API详细步骤

1. Requests

Application framework层向camera子系统发出一系列捕获数据的请求。一个请求对应于结果中的一个单元。请求封装了这些结果关于捕获数据和处理数据的所有配置信息。这些信息包括:分辨率,像素格式,sensor调整,镜头和闪光灯控制,3A操作模式,RAW转YUV处理,统计信息产生,等等。这里考虑了很多关于对结果数据的输出和处理的控制。多个请求可以一次性发出,提交请求是非阻塞模式。这些请求总是按照被接收到的顺序来处理。
在这里插入图片描述

Figure1. Camera model

2. The HAL and camera subsystem

Camera子系统包括camera流水线上各个组件的实现,比如3A算法及其处理控制。Camera HAL层为你实现这些组件提供了接口。为了保持对多个设备制造商和图像信号处理器(ISP,或者camera sensor)供应商之间的跨平台兼容性,camera流水线模块是虚拟的,并没有直接对应任何真实的ISP。但是,它与真实的处理流水线很相似,以便你能够高效地将它映射到你的硬件。另外,它很抽象,在质量,性能或者跨设备兼容性方面,不需要任何妥协就可以支持多个不同算法和操作指令。

Camera流水线也支持触发器,app framework能够初始化并打开它,比如自动聚焦。它也能向app framework发送通知,通知app关于自动聚焦被锁或者错误的事件。

在这里插入图片描述
Figure2. Camera pipeline

请注意,在最初发布的版本中,上述图表中的一些图像处理模块并没有被很好地定义。Camera流水线做了如下的假设:

·输出的RAW Bayer数据在ISP内部没有经过任何处理;

·生成的统计数据是基于raw sensor的输出数据;

·ISP中,将raw sensor的输出数据转换为YUV格式的各个处理模块没有严格的先后次序;

· 虽然展示了多个缩放和裁剪单元,但是所有的缩放单元共用一个输出区域控制(比如数字变焦)。但是每个单元可以有不同的输出分辨率和像素格式。

注:数字变焦是根据变焦倍数,从原始图像中裁剪一部分,然后放大到原始分辨率。由于是使用缩放算法直接放大的,所以其图像质量会降低。上图有三个缩放/裁剪单元,但它们共用一个输出控制器,即request control,由它来决定输出到外部缓冲区。根据application framework层的需求,最上面的缩放/裁剪单元会对从raw sensor采集的数据进行裁剪和缩放,最后输出到外边缓冲区。中间和下面的缩放/裁剪单元都是对ISP处理之后的YUV数据进行处理。中间的单元对YUV进行裁剪并缩放后,调用JPEG编码器对其进行编码,输出JPEG图像。下面的单元对YUV进行裁剪并缩放后,输出不同分辨率的YUV数据。这三个缩放/裁剪单元对输入数据也可以不进行裁剪和缩放处理。

API使用总结

这是android camera API使用步骤的简单总结。查看“ Startup and expected operation sequence”可以获得这些步骤的详细分解,以及API的调用。

1 监听并枚举所有camera设备;

2 打开设备并连接监听器;

3 配置目标用例所需的输出信息(比如静态图片,视频录制等)

4 根据目标用例创建请求;

5 发送或者重复发送这些请求;

6 接收输出的元数据和图像数据;

7 切换用例,则跳转到第3步;

HAL层操作总结

1 Framework层发送捕获数据的异步请求。

2 HAL层设备必须按照次序处理请求。对于每个请求,HAL层需要输出元数据和一个或者多个图像数据。

3 对于请求和结果都需要遵循先进先出的原则;这个数据流将被后续的请求所参考。

4 对于同一个请求,所有输出数据的时间戳必须相同,以便framework层同步输出数据,如果需要的话。

5 在请求和结果数据总,所有捕获数据的配置和状态(除了3A处理),都需要封装起来。

在这里插入图片描述

camera API的详细步骤

这段描述了使用camera API的详细步骤。其中涉及到的结构体和函数请参考文件:platform/hardware/libhardware/include/hardware/camera3.h

1 Framework层调用函数camera_module_t->common.open(),将返回一个hardware_device_t类型的结构体。

2 Framework层检查字段hardware_device_t->version,根据版本信息,实例化一个适合这个版本的camera硬件设备的句柄。例如版本号是CAMERA_DEVICE_API_VERSION_3_0,则这个设备将被转化为camera3_device_t。

3 Framework层调用函数camera3_device_t->ops->initialize(),并传递了framework层的回调函数指针。这个函数只能被调用一次,且在调用函数open()之后,在其他函数被调用之前。

4 Framework层调用函数camera3_device_t->ops->configure_streams(),向这个HAL层设备传递了输入输出的流信息。

5 Framework层分配grallocbuffer;调用函数camera3_device_t->ops->register_stream_buffers(),至少使用一个configure_streams中列举的输出流。同一个流只能被注册一次。

6 Framework层通过调用camera3_device_t->ops->construct_default_request_settings()获取用例的默认设置。这个在第三步之后任意地方进行调用。

7 Framework层使用默认设置集合中某一套设置,且保证之前注册了至少一个输出流,创建并向HAL层发第一个捕获请求。这个请求将通过调用函数camera3_device_t->ops->process_capture_request()发送到HAL层。HAL必须阻止函数返回,直到HAL准备好接收下一个请求。

8 Framework层连续地提交请求。可能会调用函数register_stream_buffers()来注册没有注册过的流,调用函数construct_default_request_settings获取其他用例所需的默认设置。

9 当一个请求的捕获开始时(sensor开始曝光),HAL层将调用函数camera3_callback_ops_t->notify()通知上层SHUTTER事件,其中包括sensor开始曝光的帧号和时间戳。调用函数process_capture_result()处理这个帧号对应的数据之前,HAL层必须发出SHUTTER通知。

10 流水线持续一些时间后,HAL层开始使用函数camera3_callback_ops_t->process_capture_result()向framework层返回处理完的图像数据。返回结果的次序与提交请求的次序完全一致。多个请求可以被一次提交,但这取决于camera HAL层设备的流水线深度。

11 工作一段时间之后,framework层可能会停止提交新的请求,等待其他请求被完成(所有buffer被填充,所有结果被返回),然后再次调用函数configure_streams()。这是为一组新的输入输出流重启camera硬件和流水线。前面配置的一些流可能会被重复使用;如果流的buffer已经注册到了HAL层,它们将不再被注册。如果有一个被注册的输出流还存在,则framework层将从第七步重新开始(否则,将从第五步开始)。

12 Framework层将调用函数camera3_device_t->common->close()结束camera会话。当framework层没有其他调用时,可以在任何时间调用这个函数,尽管这个调用会阻塞,直到所有正在处理的捕获被完成(所有结果被返回,所有buffer被填充)。函数close()返回之后,不允许HAL调用camera3_callback_ops_t的任何函数。一旦函数close()被调用,framework层将不能调用其他任何HAL层设备函数。

13 如果发生错误或者其他异步事件,HAL层必须调用函数camera3_callback_ops_t->notify()告知上层对应的错误或者事件信息。一个与设备相关的致命错误被通知上层后,HAL应该像被调用了函数close()一样。但是,在调用函数notify()之前,HAL必须取消或者完成所有未结束的数据捕获操作,以便致命错误被上报之后,framework不会收到设备的任何回调函数。除了函数close(),致命错误信息发出后,其他函数只能返回-ENODEV或者NULL。
在这里插入图片描述

整理 转自 https://blog.csdn.net/sadamoo/article/details/50370722

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页