2. Camera HAL架构概览

Android Camera HAL3(即Camera3 HAL)是Android系统从Lollipop(API 21)开始引入的新一代相机硬件抽象层架构。与HAL1相比,HAL3重新设计了数据流模型,将相机子系统抽象为管道(Pipeline),支持每帧级别的参数控制、多路输出流以及更高效的缓冲区管理。理解HAL3架构是进行V4L2驱动调试与数据流分析的基础。

2.1 Android Camera HAL3架构

HAL3架构的核心设计理念是“请求-结果”模型。上层框架(CameraService)向HAL提交捕获请求(Capture Request),HAL根据请求配置传感器、ISP和V4L2驱动,最终返回捕获结果(Capture Result)及填充好的图像缓冲区。整个架构分为三层:

  • 应用框架层(Application Framework):Camera2 API,通过Binder与CameraService通信。
  • 相机服务层(CameraService):管理权限、设备生命周期、流配置,并直接调用HAL接口。
  • HAL实现层(Camera HAL):厂商实现的动态库(如 camera.<vendor>.so),包含CameraModule、CameraDevice、CameraStream等核心模块,向下通过V4L2驱动操作硬件。
关键概念:HAL3的“管道”模型允许应用同时提交多个待处理请求,HAL内部可以流水线式处理,实现高帧率与低延迟。这与HAL1的同步操作模型有本质区别。
Android Camera HAL3 三层架构与数据流 Android Camera HAL3 三层架构与数据流 应用框架层 Camera2 API / 应用进程 相机服务层 CameraService / 流配置 & 权限管理 HAL实现层 (camera.<vendor>.so) CameraModule / CameraDevice / CameraStream V4L2驱动 / 硬件层 请求-结果模型 流水线处理

2.2 HAL与V4L2驱动的接口层

在典型的嵌入式Linux + Android平台上,Camera HAL向下与V4L2驱动交互。接口层主要完成以下工作:

  • 设备节点管理:通过 open() 系统调用打开 /dev/video* 节点,获取文件描述符。
  • 格式与分辨率协商:使用 VIDIOC_S_FMT / VIDIOC_TRY_FMT 设置传感器输出格式(如YUYV、MJPEG、NV12)和分辨率。
  • 缓冲区管理:通过 VIDIOC_REQBUFS 申请V4L2缓冲区,并使用 VIDIOC_QBUF / VIDIOC_DQBUF 进行入队/出队操作。
  • 流控制:调用 VIDIOC_STREAMON / VIDIOC_STREAMOFF 启动/停止数据流。
  • 控制参数传递:使用 VIDIOC_S_CTRL / VIDIOC_G_CTRL 设置曝光、增益、白平衡等V4L2控制参数。
HAL层操作 V4L2 IOCTL 说明
打开设备 open("/dev/video0", O_RDWR) 获取V4L2设备文件描述符
查询能力 VIDIOC_QUERYCAP 检查驱动是否支持视频捕获、流I/O等
设置格式 VIDIOC_S_FMT 配置像素格式、宽度、高度
申请缓冲区 VIDIOC_REQBUFS 分配V4L2缓冲区(mmap或用户指针模式)
入队缓冲区 VIDIOC_QBUF 将空缓冲区放入驱动队列
出队缓冲区 VIDIOC_DQBUF 从驱动队列取出已填充数据的缓冲区
启动流 VIDIOC_STREAMON 开始视频数据捕获
停止流 VIDIOC_STREAMOFF 停止视频数据捕获
设置控制 VIDIOC_S_CTRL 设置曝光、增益等参数
调试提示:在HAL层与V4L2驱动之间增加IOCTL日志(如使用 strace 或内核 dynamic debug)是定位配置问题的有效手段。重点关注 VIDIOC_S_FMT 的返回值以及 VIDIOC_REQBUFS 申请的缓冲区数量。

2.3 HAL层核心模块职责

HAL3规范定义了三个核心模块,它们共同构成了HAL实现的主体:

2.3.1 CameraModule

职责:作为HAL的入口点,负责枚举系统中可用的相机设备、加载设备信息并管理设备生命周期。

  • 实现 camera_module_t 结构体,提供 get_number_of_cameras() 和 get_camera_info() 接口。
  • 在初始化时扫描V4L2设备节点(如 /dev/video0 ~ /dev/videoN),匹配传感器驱动。
  • 为每个物理相机创建一个 CameraDevice 实例。

2.3.2 CameraDevice

职责:代表一个物理相机设备,负责处理来自CameraService的捕获请求,并管理数据流。

  • 实现 camera3_device_t 结构体,核心接口包括 initialize()、configure_streams()、process_capture_request()。
  • configure_streams():根据上层需求配置输出流(如预览流、拍照流、视频流),并在此阶段与V4L2驱动协商格式和分辨率。
  • process_capture_request():接收捕获请求,解析其中的设置(如3A参数、输出缓冲区句柄),然后驱动V4L2进行帧捕获。

2.3.3 CameraStream

职责:管理单个数据流的缓冲区队列和生命周期,是数据传递的载体。

  • 每个 CameraStream 对应一个 camera3_stream_t,包含格式、分辨率、使用标志(如GRALLOC_USAGE_HW_TEXTURE)等信息。
  • 负责将HAL层的图像缓冲区(通常通过Gralloc分配)与V4L2的缓冲区进行映射或拷贝。
  • 在多路输出流场景下,CameraStream 需要处理不同流之间的同步与裁剪。
HAL3核心模块协作关系 HAL3核心模块协作关系 CameraService CameraModule 枚举设备 / 加载信息 CameraDevice configure_streams / process_capture_request CameraStream 缓冲区管理 / 格式转换 每个CameraDevice 管理多个CameraStream
常见陷阱:在 configure_streams() 阶段,HAL必须根据所有输出流的最大分辨率来配置V4L2驱动。如果某个流请求了驱动不支持的分辨率或格式,VIDIOC_S_FMT 可能会静默调整到最接近的值,导致上层应用收到格式不匹配的缓冲区。务必在HAL层校验 S_FMT 的实际返回结果。

2.4 模块职责总结

模块 核心接口/结构体 主要职责 与V4L2的交互点
CameraModule camera_module_t 设备枚举、信息查询、模块初始化 扫描 /dev/video* 节点
CameraDevice camera3_device_t 流配置、请求处理、3A控制 VIDIOC_S_FMT, VIDIOC_REQBUFS, VIDIOC_STREAMON/OFF
CameraStream camera3_stream_t 缓冲区队列管理、格式转换、数据传递 VIDIOC_QBUF, VIDIOC_DQBUF, 缓冲区映射

理解这三个模块的职责划分,有助于在调试时快速定位问题所在:如果应用无法打开相机,问题可能在 CameraModule 的设备枚举阶段;如果预览画面卡顿或花屏,问题可能在 CameraStream 的缓冲区管理或 CameraDevice 的流配置阶段;如果拍照参数不生效,则需检查 CameraDevice 的请求处理逻辑与V4L2控制的映射关系。