Android相机-架构3

2023-10-27

目录

引言

1. Android相机的整体架构

2. 相机 HAL

2.1 AIDL相机HAL

2.2 相机 HAL3 功能

3. HAL子系统

3.1 请求

3.2 HAL和相机子系统

3.2.1 相机的管道

3.2.2 使用 Android Camera API 的步骤

3.2.3 HAL 操作摘要

3.3 启动和预期操作顺序

3.3.1 枚举、打开相机设备并创建有效会话

3.3.2 使用有效相机会话


引言

为了更深入理解相机体系,不断地反复地对相机架构的内容进行梳理和理解。

1. Android相机的整体架构

下面主要是从结构层次方面来理解Android相机体系的架构原理。先看看这个熟悉的架构图:

图1. 相机的整体架构图

这个架构图说明的是从 应用层 到 HAL层的原理

应用框架:通过Activity 或者 Service 调用 Camera API v2来实现应用的业务逻辑开发,比如相机应用的拍照逻辑,预览逻辑,录像逻辑等等。其中涉及到的两个核心组件:CameraDevice 和 CameraManager

Native框架:提供了CameraDevice 和CameraCaptureSession的实现

Native框架通过HAL层进行硬件的管理和控制。换句话说,应用之所以能够正确操作相机硬件,就是因为HAL层提供了接口。典型的接口包括:

1)枚举单个设备并管理器状态的接口:ICameraProvider

2)相机设备的接口:ICameraDevice

3)激活的相机设备会话接口:ICameraDeviceSession

相机的一些能力还需要通过Service服务的方式向上层提供出去的。具体的实际代码在:

frameworks/av/services/camera/libcameraservice/CameraService.cpp

这样,我们使用相机的时候就会有3个运行的进程交互协作共同完成用户的业务需求。而这3个进程之间的通信是通过AIDL的方式来实现的。实现的IPC binder接口包括:

1)已打开的特定相机设备接口:ICameraDevice

2)相机服务的接口:ICameraService;

3)应用框架中CameraDevice的回调接口:ICameraDeviceCallbacks,

4)应用框架中CameraService的回调接口:ICameraServiceListener

就这样,Android相机体系架构中,Android应用的业务逻辑的实现是通过Camera API v2来实现,而Camera API v2 又是通过Native框架实现,Native框架通过再硬件抽象层(Camera HAL 层)控制和管理应用,Camera HAL则是通过内核驱动直接操作硬件。通过这样的一种关联交互的方式实现了相机的业务逻辑与硬件的交互。

2. 相机 HAL

从整体架构中,可以发现,Android相机的实现主要是依靠 相机 HAL实现的。换句话说,Android的相机HAL 是连接 android.hardware.camera2 上层相机框架 API 与 底层相机驱动和硬件的 桥梁。从Android8.0引入了Treble,用于将相机HAL API切换到由HAL接口语言HIDL定义的稳定接口,从Android 13开始,相机HAL接口使用AIDL进行开发。

2.1 AIDL相机HAL

对于搭载 Android 13 或更高版本的设备,该相机框架包含对 AIDL 相机 HAL 的支持。该相机框架还支持 HIDL 相机 HAL,不过,在 Android 13 或更高版本中添加的相机功能只能通过 AIDL 相机 HAL 接口使用。如需在升级到 Android 13 或更高版本的设备上实现此类功能,设备制造商必须将其 HAL 进程从使用 HIDL 相机接口迁移到使用 AIDL 相机接口。

补充说明:Android中,适用于HAL的AIDL是从Android11开始的。设计初衷其实是由于AIDL和HIDL都是为了跨进程通信设计的。由于AIDL具备了稳定性的支持,这样如果只是用一个方式设计的话就意味着仅使用一个IPC运行时环境来实现整个堆栈。化繁为简更易于调试,优化和维护。同时AIDL的版本控制系统也由于HIDL。

AIDL 相机 HAL 规范位于以下位置:

相机提供程序: hardware/interfaces/camera/provider/aidl/
相机设备: hardware/interfaces/camera/device/aidl/
相机元数据: hardware/interfaces/camera/metadata/aidl/
常见数据类型: hardware/interfaces/camera/common/aidl/
对于迁移到 AIDL 的设备,设备制造商可能需要修改 Android SELinux 政策 (sepolicy) 和 RC 文件,具体取决于代码结构。

验证 AIDL 相机 HAL
如需测试 AIDL 相机 HAL 实现,请确保设备已通过所有 CTS 和 VTS 测试。Android 13 引入了 AIDL VTS 测试 VtsAidlHalCameraProvider_TargetTest.cpp。

2.2 相机 HAL3 功能

我们已经知道相机HAL是连接应用和底层驱动硬件的桥梁。下面我们继续聊聊 相机HAL 的功能。

HAL从HAL1发展到HAL3,从而也就意味着重新设计了Android Camer API,而其中的目标都是为了在Android设备上构建高质量的相机应用,更稳定,性能更好。

相机HAL3 的子系统将操作模式构建为单个统一视图,该视图可用于实现之前的任何模式和其他几种模式,例如连拍模式。这使得用户可以更好地控制焦点和曝光,并进行更多的后处理,如降噪、对比度和锐化。此外,这种简化的视图使应用程序开发人员更容易使用相机的各种功能。

API将摄像机子系统建模为一个管道,以1:1的基础将传入的帧捕获请求转换为帧。请求封装了关于帧的捕获和处理的所有配置信息。这包括分辨率和像素格式;手动传感器、镜头和闪光灯控制;3A操作模式;RAW->YUV处理控制;统计生成;等等

简单地说,应用程序框架从相机子系统请求帧,相机子系统将结果返回到输出流。此外,为每组结果生成包含诸如颜色空间和镜头明暗处理之类的信息的元数据。可以将相机HAL3视为相机HAL1的单向流的管道。它将每个捕获请求转换为传感器捕获的一张图像,并将其处理为:

  • 包含有关捕获的元数据的 Result 对象。
  • 图像数据的 1 到 N 个缓冲区,每个缓冲区会进入自己的目标 Surface。

可能的输出 Surface 组经过预配置:

  • 每个 Surface 都是一个固定分辨率的图像缓冲区数据流的目标位置。
  • 一次只能将少量 Surface 配置为输出(约 3 个)。

一个请求中包含所需的全部捕获设置,以及要针对该请求将图像缓冲区(从总配置组)推送到其中的输出 Surface 的列表。

请求可以只发生一次(使用 capture()),也可以无限重复(使用 setRepeatingRequest())。

捕获的优先级高于重复请求的优先级。

图2. 相机的核心操作模型

3. HAL子系统

3.1 请求

应用框架向相机子系统发出请求
一个请求对应一组结果

请求包含的信息:
1)分辨率和像素格式
2)手动传感器,镜头,闪光灯等控件
3)3A操作模式;
4)RAW到YUV处理控制
5)统计信息

一次可以发出多个请求
提交请求不会阻塞
请求始终按照接收的顺序进行处理。

图3. 相机模型

此相机模型可以看到从应用请求到HAL层返回结果的整个流程。结合我们上面架构和HAL的知识梳理,会更容易理解图3 所描述的相机模型。暂且只需要直观地了解一下大致的请求与结果返回的路径。我们继续梳理。

3.2 HAL和相机子系统

3.2.1 相机的管道

HAL子系统包括了相机管道中的组件的实现
HAL子系统提供实现组件的接口,如:3A算法和处理控件
HAL子系统可以支持不同设备制造商,不同信号处理器的跨平台兼容性
HAL子系统支持不同的算法和运算顺序,不影响质量,效率或者跨设备的兼容性
相机管道还支持应用框架可以启动触发器来开启自动对焦等功能。它还会将通知发送回应用框架,以通知应用自动对焦锁定或错误等事件。

所以理解的相机的管道,就基本理解了相机的HAL 子系统了。

图4. 相机管道

从图4的相机管道模型图中,可以了解到:

1)RAW Bayer 输出在 ISP 内部不经过任何处理。
2)统计信息根据原始传感器数据生成。
3)将原始传感器数据转换为 YUV 的各种处理块按任意顺序排列。
4)当显示多个刻度和剪裁单元时,所有缩放器单元共享输出区域控件(数字缩放)。不过,每个单元都可能具有不同的输出分辨率和像素格式。

3.2.2 使用 Android Camera API 的步骤

下面先简要介绍了使用 Android Camera API 的步骤。

1)监听和枚举相机设备。
2)打开设备并连接监听器。
3)配置目标使用情形的输出(如静态捕获、录制等)。
4)为目标使用情形创建请求。
5)捕获/重复请求和连拍。
6)接收结果元数据和图片数据。
7)切换使用情形时,返回到第 3 步。

3.2.3 HAL 操作摘要

1)捕获的异步请求来自于框架。
2)HAL 设备必须按顺序处理请求。对于每个请求,均生成输出结果元数据以及一个或多个输出图像缓冲区。
3)请求和结果以及后续请求引用的信息流遵守先进先出规则。
4)指定请求的所有输出的时间戳必须完全相同,以便框架可以根据需要将它们匹配在一起。
5)所有捕获配置和状态(不包括 3A 例程)都包含在请求和结果中。

图5. 相机HAL

图中的 1-9 代表这从request到result的顺序,最先的请求1,得到了结果也是排在最前面的。

3.3 启动和预期操作顺序

先看看我们操作的流程图:

图6. 相机的操作流程

3.3.1 枚举、打开相机设备并创建有效会话

1)初始化后,框架开始监听实现 ICameraProvider 接口的任何现有CameraProvider。如果存在一个或多个CameraProvider,框架将尝试建立 connection。
2)框架通过 ICameraProvider::getCameraIdList() 枚举相机设备。
3)框架通过调用相应的 ICameraProvider::getCameraDeviceInterface_VX_X() 来实例化一个新的 ICameraDevice。
4)框架调用 ICameraDevice::open() 来创建一个新的有效捕获会话 ICameraDeviceSession。

3.3.2 使用有效相机会话

1)框架调用 ICameraDeviceSession::configureStreams() 并传入到 HAL 设备的输入/输出流列表。

2)框架通过调用 ICameraDeviceSession::constructDefaultRequestSettings() 为某些用例请求默认设置。这可能会在 ICameraDevice::open 创建 ICameraDeviceSession 之后的任何时间发生。

3)框架通过基于某一组默认设置的设置以及框架之前注册的至少一个输出流来构造第一个捕获请求并将其发送到 HAL。此请求通过 ICameraDeviceSession::processCaptureRequest() 发送到 HAL。HAL 必须阻止此调用返回,直到准备好发送下一个请求为止。

4)框架继续提交请求并根据需要调用 ICameraDeviceSession::constructDefaultRequestSettings() 以获取其他用例的默认设置缓冲区。

5)当请求捕获开始(传感器开始曝光以进行捕获)时,HAL 会调用 ICameraDeviceCallback::notify() 并显示 SHUTTER 消息,包括帧号和开始曝光的时间戳。此通知回调不必在对请求第一次调用 processCaptureResult() 之前发生,但直到针对相应的捕获调用 notify() 之后,才会向应用提供有关该捕获的结果。

6)经过一定的 pipeline 延迟后,HAL 开始使用 ICameraDeviceCallback::processCaptureResult() 将完成的捕获返回到框架。这些捕获按照与提交请求相同的顺序返回。一次可发起多个请求,具体取决于相机 HAL 设备的管道深度。

启动之后可能的三种状态:

1)框架停止提交新的请求,等待现有的捕获完成,然后再次调用。
2)正常结束:框架结束相机会话
3)异常结束:发生错误或者其他异步事件而返回。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android相机-架构3 的相关文章

随机推荐

  • unable to boot the simulator,无法启动模拟器已解决

    我在百度上所搜的都是以前的老方法 新版的Mac已经没有Recovery了 因此我只好去bing上查找资料 方法很简单 用Mac安装镜像进入Recovery模式 然后输入 csrutil disable 就行了 剩下的和原来的方法一致
  • 浮点数和整数之间的转换

    当一个整数int i 12345被强制转换为一个FLOAT型变量 float f float i 假设sizeof int 32 float为单精度 sizeof float 32 那么i 12345 十进制 000000000000000
  • UE4_聚合图

    UE4 聚合图
  • 【Python 1-0】10个学习Python的理由以及Python的优势有哪些?

    Python的由来 首发地址 Python的创始人是吉多 范罗苏姆 1989年他在阿姆斯特丹的CWI工作 圣诞节期间 吉多 范罗苏姆为了打发圣诞节的无聊 决定开发一个新的脚本解释程序 作为ABC 语言的一种继承 之所以选择Python作为编
  • Maven覆盖私服上的jar包,本地仓库无法更新的问题

    在上传第三方jar包到私服环境时 第一次上传成功后 突然发现上传的jar包有问题 但是因为已经指定了版本号 并且是release版本的jar包 因为不想更换版本号 所以再重复上传正确的jar包 就会出现如下错误 一种解决办法是指定另外一个版
  • Gitflow工作流程

    在工作场合实施Git的时候 有很多种工作流程可供选择 此时反而会让你手足无措 本文罗列了企业团队最常用的一些Git工作流程 包括Centralized Workflow Feature Branch Workflow Gitflow Wor
  • Container命令ctr,crictl的用法

    Container命令ctr crictl的用法 版本 ctr containerd io 1 4 3 containerd 相比于docker 多了namespace概念 每个image和container 都会在各自的namespace
  • 通过Vue.js的axios请求WFS数据并处理请求回来的XML文件

    前端小白的第一个博客 前言 这个是在GIS开发过程中遇到的一个小问题 因为里面包含了蛮多的知识点 故将其记录 废话不多说进入正文 正文 此次需要解决的问题是通过wfs接口来获取到一些需要的内容 然后以这些内容为基础进行一系列的操作 以下展示
  • 1.3远程控制及文件传输

    我们经常用的是Windows操作系统 又经常需要与Ubuntu进行文件传输 同时为了能在Windows上操作我们的Ubuntu 这里推荐一个文件传输和一个远程控制的程序 文件传输WinSCP 官方下载地址 https sourceforge
  • VsCode官网快速下载

    VsCode官网 以Win10下载为例 问题描述 下载时 发现速度很慢 甚至会没有下载速度 如下图 解决方法 右键复制这个下载链接 将其前半部分修改为vscode cdn azure cn 例如 原下载链接 https az764295 v
  • Codeforces 600C Make Palindrome 【贪心 找字典序最小回文串】

    一 题目概述 C Make Palindrome time limit per test 2 seconds memory limit per test 256 megabytes input standard input
  • 如何在Anaconda安装opencv,下面分享一下教程

    1 首先下载opencv安装包 下载地址 https download csdn net download qq 42375391 12333992 2 安装完成后 在Anaconda Prompt内使用pip install完整路径文件名
  • 算法:模拟思想算法

    文章目录 实现原理 算法思路 典型例题 替换所有问号 提莫攻击 N字型变换 外观序列 总结 本篇总结的是模拟算法 实现原理 模拟算法的实现原理很简单 就是依据题意实现题意的目的即可 考察的是你能不能实现题目题意的代码能力 算法思路 没有很明
  • openwrt 自动签到插件-食用指南

    目录 openwrt 自动签到插件下载 openwrt 插件安装需要的依赖 openwrt 插件安装 文件上传 openwrt 自动签到配置 设置详情 Cookie获取失败 解决方法 Charles 抓包获取Cookie openwrt 配
  • 计算机设备问题代码43,双击unknown device由于该设备有问题Windows已将其停止(代码 43)怎么办解决教程...

    金士顿U盘做的启动盘 8G 在别人的电脑上储存文件正常 但在自己的电脑上无法识别 在设备管理器中显示黄色叹号 属性显示 该设备存在问 题 windows已将其停止 代码43 本机win7系统 别人电脑为XP系统 已将 禁用 注册表 dos设
  • Linux 阻塞IO(等待队列)原理及架构

    一 阻塞操作 阻塞操作是指在执行折本操作时 若不能获得自愿 则挂起进程直到满足可操作性的条件后在进行操作 被挂起的进程进入休眠状态 被从调度器的运行队列移走 直到等待的条件被满足 假设recvfrom函数是一个系统调用 阻塞不是低效率 如果
  • vue -- 验证码

  • 25-python函数(低阶)

    一 函数的作用 函数的本质就是将一段具有独立功能的代码块整合到一个整体并命名 在需要的时候通过调用函数名完成某种需求 以提高代码的利用率 从而在稳定系统的同时减轻程序员的工作 二 函数的使用过程 函数使用分为两个步骤 先定义 后调用 定义函
  • Java设计模式之状态模式

    本文继续介绍23种设计模式系列之策略模式 何时使用 State模式在实际使用中比较多 适合 状态 的切换 因为我们经常会使用If else if else 进行状态切换 如果针对状态的这样判断切换反复出现 我们就要联想到是否可以采取Stat
  • Android相机-架构3

    目录 引言 1 Android相机的整体架构 2 相机 HAL 2 1 AIDL相机HAL 2 2 相机 HAL3 功能 3 HAL子系统 3 1 请求 3 2 HAL和相机子系统 3 2 1 相机的管道 3 2 2 使用 Android