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 请求到最终帧数据返回的完整路径。每个箭头代表一次跨进程或跨模块调用。

Android Camera 完整调用链路架构图 Android Camera 完整调用链路 (App → HAL3 → Kernel) App (Camera2 API) openCamera / createCaptureSession CameraService 权限 / 会话 / 流配置 CameraProvider HAL3 接口适配层 HAL3 (camera3_ops) configure_streams / process_capture Kernel (V4L2 / ISP) sensor / CSI / DMA-buf 关键数据流与回调路径 ① openCamera() App → CameraService → CameraProvider → HAL3 ② configureStreams() CameraService 协商流格式 → HAL3 分配 pipeline ③ processCaptureRequest() App 下发 request → HAL3 填充 output buffers ④ notify() / processCaptureResult() HAL3 异步回调 → CameraService → App ⑤ Buffer 流转 App 注册 Surface → BufferQueue → HAL3 dequeue ⑥ 错误处理路径 HAL3 ERROR_DEVICE → CameraService 断开 → App onDisconnected ⑦ Metadata 流 HAL3 填充 result metadata → CameraService 解析 → App 回调

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 传递

整个链路中最容易出问题的两个边界是:

  1. CameraService ↔ CameraProvider(HIDL 边界):使用 Binder 驱动的 HIDL 接口。如果 CameraProvider 进程崩溃,CameraService 会收到死亡通知,进而断开所有 App 连接。
  2. 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 处理流水线或中断响应时间。