2. Android Camera框架全景:从App到CameraService到HAL3的完整调用链路
Android Camera 框架从上至下横跨应用层、框架层、硬件抽象层和内核驱动层。理解这条完整的调用链路,是进行 HAL3 适配与调试的基础。本章将逐层拆解数据流与控制流的传递路径,并聚焦于关键接口与边界。
核心认知: Camera 框架的设计哲学是“分层隔离”——应用开发者只面对 Android SDK,OEM 厂商只面对 HAL3 接口,中间层由 CameraService 与 CameraProvider 进程透明地桥接双方。
2.1 四层架构总览
整个 Camera 软件栈可划分为四个逻辑层,每层都有明确的职责与边界。
| 层次 | 进程/组件 | 核心职责 | 关键接口 |
|---|---|---|---|
| 应用层 | App / SDK | 调用 Camera API2,管理预览、拍照、录像生命周期 | android.hardware.camera2.* |
| 框架层 | CameraService | 权限校验、会话管理、流配置协商、CameraDevice 生命周期 | AIDL / CameraService.h |
| HAL 层 | CameraProvider / HAL3 | 实现 camera3_device_ops_t,管理硬件资源与 pipeline |
camera3.h / HIDL |
| 内核层 | V4L2 / ISP 驱动 | 控制 sensor、CSI 接收、ISP 处理、buffer 搬运 | V4L2 ioctl / DMA-buf |
调试启示: 大部分 Vendor 层适配问题发生在 HAL3 与内核驱动之间。当 App 报错“Camera service disconnected”时,问题往往出在 CameraProvider 进程崩溃,而非 App 本身。
2.2 完整调用链路 SVG 架构图
下图展示了从 App 发起打开 Camera 请求到最终帧数据返回的完整路径。每个箭头代表一次跨进程或跨模块调用。
2.3 逐层调用详解
2.3.1 应用层:Camera2 API 调用模式
App 通过 CameraManager 打开相机,然后创建 CameraCaptureSession 并下发 CaptureRequest。典型的调用序列如下:
// 1. 获取 CameraManager
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
// 2. 打开相机(异步回调)
manager.openCamera(cameraId, stateCallback, handler);
// 3. 在 onOpened 中创建会话
cameraDevice.createCaptureSession(
Arrays.asList(surfaceView.getHolder().getSurface()),
sessionCallback, handler);
// 4. 下发预览请求
CaptureRequest.Builder builder =
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(surfaceView.getHolder().getSurface());
captureSession.setRepeatingRequest(builder.build(), captureCallback, handler);
调试要点: App 层最常见的错误是
CameraAccessException 和 IllegalStateException。前者通常表示 CameraService 无法连接,后者表示状态机异常(如重复 close)。
2.3.2 框架层:CameraService 内部状态机
CameraService 运行在 cameraserver 进程中,负责管理多个 CameraDevice 实例。其核心状态机包括:
- CLOSED:初始状态,设备未打开。
- OPEN:设备已打开,但未配置流。
- CONFIGURED:流已配置,可以下发 request。
- ACTIVE:正在处理 capture request。
- ERROR:设备发生致命错误,需要关闭。
CameraService 通过 HIDL 与 CameraProvider 通信。在 Android 10+ 中,CameraProvider 被分离为独立进程(android.hardware.camera.provider),增强了稳定性。
2.3.3 HAL3 层:camera3_device_ops_t 接口表
HAL3 的核心是 camera3_device_ops_t 结构体,Vendor 层必须实现以下关键函数指针:
| 函数指针 | 触发时机 | 典型调试关注点 |
|---|---|---|
initialize() |
CameraService 打开设备后 | 回调接口注册、资源预分配 |
configure_streams() |
App 调用 createCaptureSession | 流格式/分辨率/buffer 数量协商 |
process_capture_request() |
App 下发 capture request | settings 解析、buffer 填充、3A 触发 |
flush() |
App 关闭会话或 abort | 清空 pending request,避免死锁 |
dump() |
dumpsys camera 调用 | 输出内部状态,用于在线调试 |
2.3.4 内核层:V4L2 与 ISP 交互
HAL3 通过 V4L2 接口与内核驱动交互。典型的 ioctl 调用序列包括:
// 打开设备
fd = open("/dev/video0", O_RDWR);
// 查询能力
ioctl(fd, VIDIOC_QUERYCAP, &cap);
// 设置格式
struct v4l2_format fmt = {0};
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt.fmt.pix_mp.width = 1920;
fmt.fmt.pix_mp.height = 1080;
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
ioctl(fd, VIDIOC_S_FMT, &fmt);
// 请求 buffer
struct v4l2_requestbuffers req = {0};
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
req.memory = V4L2_MEMORY_DMABUF;
ioctl(fd, VIDIOC_REQBUFS, &req);
// 入队 buffer
ioctl(fd, VIDIOC_QBUF, &buf);
// 启动流
ioctl(fd, VIDIOC_STREAMON, &type);
// 等待帧数据(poll + dequeue)
poll(fds, 1, -1);
ioctl(fd, VIDIOC_DQBUF, &buf);
常见陷阱: V4L2 的 buffer 队列管理必须与 HAL3 的 buffer 生命周期严格同步。如果 HAL3 在
process_capture_request 中未及时归还 buffer,会导致内核侧 dequeue 超时,进而触发 ERROR_REQUEST 回调。
2.4 关键边界:跨进程通信与 Buffer 传递
整个链路中最容易出问题的两个边界是:
- CameraService ↔ CameraProvider(HIDL 边界):使用 Binder 驱动的 HIDL 接口。如果 CameraProvider 进程崩溃,CameraService 会收到死亡通知,进而断开所有 App 连接。
- HAL3 ↔ Kernel(V4L2 边界):通过 ioctl 和 DMA-buf 传递帧数据。Vendor 层需要确保 buffer 的物理连续性和 cache 一致性。
调试工具链提示: 在后续章节中,我们将使用
lsof 查看 HAL3 进程打开的文件描述符,使用 dmesg 捕获内核驱动错误,使用 systrace 分析跨进程调用延迟。这些工具将帮助你快速定位边界问题。
2.5 调用链路时序总结
以下时序表总结了从 App 发起预览到第一帧显示的完整调用顺序:
| 步骤 | 发起方 | 接收方 | 关键操作 | 耗时参考 |
|---|---|---|---|---|
| 1 | App | CameraService | openCamera() → 权限检查 → 创建 CameraDevice | 50-200ms |
| 2 | CameraService | CameraProvider | HIDL open() → HAL3 initialize() | 10-50ms |
| 3 | App | CameraService | createCaptureSession() → 流配置协商 | 30-100ms |
| 4 | CameraService | HAL3 | configure_streams() → 分配 pipeline | 20-80ms |
| 5 | App | HAL3 | setRepeatingRequest() → process_capture_request() | 5-10ms |
| 6 | HAL3 | Kernel | V4L2 QBUF → STREAMON → 等待帧中断 | 16-33ms (取决于帧率) |
| 7 | Kernel | HAL3 | 帧中断 → DQBUF → 填充 output buffer | 1-5ms |
| 8 | HAL3 | CameraService | process_capture_result() → 回调 metadata | 1-3ms |
| 9 | CameraService | App | onCaptureCompleted() → 显示预览帧 | 1-2ms |
性能基线: 从步骤 5 到步骤 9 的端到端延迟(App 下发 request 到收到第一帧回调)通常应小于 50ms。如果超过 100ms,说明 HAL3 或内核驱动存在瓶颈,需要检查 buffer 分配、ISP 处理流水线或中断响应时间。