Android camera HAL v3 介绍
注:原翻译作者不可考。
来源:https://source.android.com/devices/camera/camera3_requests_hal
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。但是,它与真实的处理流水线很相似,以便你能够高效地将它映射到你的硬件。另外,它很抽象,在质量,性能或者跨设备兼容性方面,不需要任何妥协就可以支持多个不同算法和操作指令。
The camera pipeline also supports triggers that the app framework can initiate to turn on things such as auto-focus. Italso sends notifications back to the app framework, notifying apps of events such as an auto-focus lock or errors.
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层操作总结
· Framework层发送捕获数据的异步请求。
· HAL层设备必须按照次序处理请求。对于每个请求,HAL层需要输出元数据和一个或者多个图像数据。
· 对于请求和结果都需要遵循先进先出的原则;这个数据流将被后续的请求所参考。
· 对于同一个请求,所有输出数据的时间戳必须相同,以便framework层同步输出数据,如果需要的话。
· 在请求和结果数据总,所有捕获数据的配置和状态(除了3A处理),都需要封装起来。
Figure3. Camera HAL overview
3.Startup and expected operation sequence
这段描述了使用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。
4.Operational modes
Camera HAL层v3版本的设备实现两种可能的操作模式之一:limited模式和full模式。新的高端设备预计会支持full模式。Limited模式与camera HAL层v1版本一样,对硬件需求很低,用于旧的或者低价设备。Full模式是limited模式的超集,如上面所述,它们有着基本上一样的操作流程。
Camera HAL层必须使用静态元数据android.info.supportedHardwareLevel指明其所支持的模式。0表示支持limited模式,1表示支持full模式。
简单来讲,limited模式设备不允许应用程序控制捕获数据信息的设置(3A控制除外),大分辨率图像的高帧率捕获,raw数据的获取,或者上面所说的最大视频分辨率的YUV输出流(对于大图像只支持JPEG)。
Limited模式行为的细节如下:
· Limited模式的设备不需要实现请求配置与实际捕获图像数据的完全匹配。相反,将来有时改变配置将更高效,可能也不需要一个配置必须对应一个同样的输出帧。快速改变配置可能会使得某些配置从来没有被使用过。但是,有高分辨率(大于1080P)输出buffer的捕获必须使用指定的配置(处理速度的描述如下)。
· 在limited模式下,有高分辨率(大于1080P)输出buffer的捕获在函数process_capture_request()中会阻塞,直到所有输出buffer都被填充。Full模式HAL层设备必须按照静态元数据中指定的速率,处理相应像素格式的高分辨率请求的序列。HAL层调用函数process_capture_result()产生输出结果;framework层需要为函数process_capture_request()做好准备,然后阻塞,直到limited模式设备的高分辨率捕获请求被函数process_capture_result()执行完毕。
· Limited设备不需要支持大多数的配置、结果、静态信息。只有下面的配置期待被limited模式HAL层设备所支持:
o android.control.aeAntibandingMode(controls)
o android.control.aeExposureCompensation(controls)
o android.control.aeLock(controls)
o android.control.aeMode(controls)
o [OFF meansON_FLASH_TORCH]
o android.control.aeRegions(controls)
o android.control.aeTargetFpsRange(controls)
o android.control.afMode(controls)
o [OFF means infinityfocus]
o android.control.afRegions(controls)
o android.control.awbLock(controls)
o android.control.awbMode(controls)
o [OFF not supported]
o android.control.awbRegions(controls)
o android.control.captureIntent(controls)
o android.control.effectMode(controls)
o android.control.mode(controls)
o [OFF not supported]
o android.control.sceneMode(controls)
o android.control.videoStabilizationMode(controls)
o android.control.aeAvailableAntibandingModes(static)
o android.control.aeAvailableModes(static)
o android.control.aeAvailableTargetFpsRanges(static)
o android.control.aeCompensationRange(static)
o android.control.aeCompensationStep(static)
o android.control.afAvailableModes(static)
o android.control.availableEffects(static)
o android.control.availableSceneModes(static)
o android.control.availableVideoStabilizationModes(static)
o android.control.awbAvailableModes(static)
o android.control.maxRegions(static)
o android.control.sceneModeOverrides(static)
o android.control.aeRegions(dynamic)
o android.control.aeState(dynamic)
o android.control.afMode(dynamic)
o android.control.afRegions(dynamic)
o android.control.afState(dynamic)
o android.control.awbMode(dynamic)
o android.control.awbRegions(dynamic)
o android.control.awbState(dynamic)
o android.control.mode(dynamic)
o android.flash.info.available(static)
o android.info.supportedHardwareLevel(static)
o android.jpeg.gpsCoordinates(controls)
o android.jpeg.gpsProcessingMethod(controls)
o android.jpeg.gpsTimestamp(controls)
o android.jpeg.orientation(controls)
o android.jpeg.quality(controls)
o android.jpeg.thumbnailQuality(controls)
o android.jpeg.thumbnailSize(controls)
o android.jpeg.availableThumbnailSizes(static)
o android.jpeg.maxSize(static)
o android.jpeg.gpsCoordinates(dynamic)
o android.jpeg.gpsProcessingMethod(dynamic)
o android.jpeg.gpsTimestamp(dynamic)
o android.jpeg.orientation(dynamic)
o android.jpeg.quality(dynamic)
o android.jpeg.size(dynamic)
o android.jpeg.thumbnailQuality(dynamic)
o android.jpeg.thumbnailSize(dynamic)
o android.lens.info.minimumFocusDistance(static)
o android.request.id(controls)
o android.request.id(dynamic)
o android.scaler.cropRegion(controls)
o [ignores (x,y),assumes center-zoom]
o android.scaler.availableFormats(static)
o [RAW not supported]
o android.scaler.availableJpegMinDurations(static)
o android.scaler.availableJpegSizes(static)
o android.scaler.availableMaxDigitalZoom(static)
o android.scaler.availableProcessedMinDurations(static)
o android.scaler.availableProcessedSizes(static)
o [full resolution notsupported]
o android.scaler.maxDigitalZoom(static)
o android.scaler.cropRegion(dynamic)
o android.sensor.orientation(static)
o android.sensor.timestamp(dynamic)
o android.statistics.faceDetectMode(controls)
o android.statistics.info.availableFaceDetectModes(static)
o android.statistics.faceDetectMode(dynamic)
o android.statistics.faceIds(dynamic)
o android.statistics.faceLandmarks(dynamic)
o android.statistics.faceRectangles(dynamic)
o android.statistics.faceScores(dynamic)
5. Interaction between the application capturerequest, 3A control, and the processing pipeline
根据3A控制模块的配置,camera流水线会忽略应用程序请求中的一些参数,而使用3A控制模块提供的值代替。例如,当自动曝光开启时,曝光时间,帧率,sensor的敏感参数都由3A算法控制,应用程序提供的值全被忽略。3A事务为帧所设置的参数值必须包含在输出的元数据中。下面的表格描述了3A模块的不同模式和被这些模式所控制的属性。
属性的定义见文件platform/system/media/camera/docs/docs.html。
Parameter | State | Properties controlled |
android.control. aeMode | OFF | None |
ON | android.sensor.exposureTime android.sensor.frameDuration android.sensor.sensitivity android.lens.aperture (if supported) android.lens.filterDensity (if supported) | |
ON_AUTO_FLASH | Everything is ON, plus android.flash.firingPower, android.flash.firingTime, and android.flash.mode | |
ON_ALWAYS_FLASH | Same as ON_AUTO_FLASH | |
ON_AUTO_FLASH_RED_EYE | Same as ON_AUTO_FLASH | |
android.control. awbMode | OFF | None |
WHITE_BALANCE_* | android.colorCorrection.transform. Platform-specific adjustments if android.colorCorrection.mode is FAST or HIGH_QUALITY. | |
android.control. afMode | OFF | None |
FOCUS_MODE_* | android.lens.focusDistance | |
android.control. videoStabilization | OFF | None |
ON | Can adjust android.scaler.cropRegion to implement video stabilization | |
android.control. mode | OFF | AE, AWB, and AF are disabled |
AUTO | Individual AE, AWB, and AF settings are used | |
SCENE_MODE_* | Can override all parameters listed above. Individual 3A controls are disabled. |
所列的3A算法的控制大部分都是与旧的API参数一一匹配(例如曝光补偿,场景模式,或者白平衡模式)。
图2中的图像处理模块的控制都是基于一个相似的原则,通常每个模块有三中模式:
· OFF:这个处理模块不使能。去马赛克,颜色校正和tone曲线调整模块必须使能。
· FAST:在这种模式,与off模式相比,处理模块不会降低输出帧率,但是对于产生高质量输出时就不受这个限制了。典型地,它被用于预览或者视频录制模式,或者静态图片的快速捕获。在一些设备中,这种模式与OFF模式一样(不工作就不会降低帧率);在一些设备中,它与HIGH_QUALITY模式一样(高质量处理也不会降低帧率)。
· HIGHQUALITY:在这种模式中,处理模块产生最高质量的结果,如果需要会降低输出帧率。典型地,它被用于高质量静态图片的捕获。一些包括手动控制的模块,可以替代FAST或者HIGHQUALITY。例如,图像校正模块支持一个颜色转换矩阵,而tone曲线调整支持一个任意全局tone映射曲线。
一个camera子系统能够支持的最大帧率是多个元素的函数:
· 输出图像流所需要的分辨率
· Imager对binning / skipping模式的支持
· imager接口的带宽
· 各个ISP处理模块的带宽
因为对于不同的ISP和sensor,这些因子有很大的变化,camera HAL层接口想要抽象一个尽可能简单的带宽限制模型。这个模型有如下特性:
· Sensor总是输出能满足应用程序请求的输出流大小的最小分辨率图像数据。这个最小分辨率至少与被请求的最大输出流大小一样大。
· 因为任何情况可能会用到被配置的输出流的几个或者所有,所以sensor和ISP必须被配置为能够将一个图像同时缩放到所有输出流中。
· JPEG流就像请求的被处理的YUV流;在请求中,它们直接被当作JPEG流来引用。
· JPEG处理器能够同时处理camera流水线的剩余部分,但不能在同一个时刻处理多于一张的图片。
(全文完)