Camera Metadata 机制

王者杯·14天创作挑战营·第6期 10w+人浏览 507人参与

Camera HAL3 的 Metadata 机制 是其实现强大、灵活的 Per-Frame Control(逐帧控制) 能力的核心。它本质上是一个结构化的键值对(Tag-Value)数据容器,承载着相机系统的配置、状态和结果信息,在应用程序(APP)、框架(Framework, FWK)和硬件抽象层(HAL)之间高效穿梭。

以下是其机制的详细解释:

1. Metadata 的本质和作用:信息容器与穿梭桥梁

  • 结构化数据容器: Metadata 不是原始图像数据(YUV, RAW),而是描述图像数据如何被捕获和处理、相机当前状态是什么、以及捕获结果如何的关键信息集合。它使用预定义的 Tag(标签/枚举) 来索引对应的 Value(值)
  • 标准化通信语言: 它定义了一套 APP、FWK、HAL 三方都能理解和操作的标准数据格式和语义。这使得不同厂商的 HAL 实现能够与 Android 相机框架和应用程序无缝协作。
  • 穿梭作用:metadata分成control、dynamic以及static三类
    • (Request)APP -> FWK -> HAL : APP 通过 Metadata (CaptureRequest) 向 FWK 和 HAL 传达其拍摄意图和具体参数要求(例如:曝光时间、感光度 ISO、对焦模式、目标区域、处理参数等)。FWK 会进行权限检查、参数合理性校验和可能的转换/补全,然后将请求 Metadata 传递给 HAL。
    • (Result)HAL -> FWK -> APP : HAL 执行完一个 CaptureRequest 后,将捕获的结果状态、实际使用的参数、以及图像相关的动态信息填充到 Metadata (CaptureResult) 中,通过 FWK 返回给 APP。FWK 可能也会添加一些框架层面的信息。
    • (Static)HAL -> FWK -> APP : 设备启动或相机首次打开时,HAL 会向 FWK 提供描述相机设备固有能力和限制的静态 Metadata。FWK 缓存这些信息并提供给 APP 查询。这些信息在相机会话期间通常不会改变。
  • 承载信息类型: Metadata 承载的信息极其丰富,包括但不限于:
    • 控制参数(曝光、对焦、白平衡、闪光灯、降噪、畸变校正等)
    • 传感器信息(尺寸、像素阵列、原始模式支持等)
    • 镜头信息(焦距、光圈范围、光学防抖能力等)
    • 处理单元信息(支持的 YUV/RAW 格式、最大分辨率、后处理效果等)
    • 3A 状态(AE/AF/AWB 的当前模式、锁定状态、区域等)
    • 捕获结果(时间戳、帧号、实际使用的曝光/增益、3A 收敛状态、陀螺仪数据等)
    • 设备特性(支持的硬件等级、能力枚举等)

2. Metadata 的三类划分及其在 Per-Frame Control 中的角色

为了实现高效的逐帧控制,Metadata 被逻辑上划分为三类,每类有不同的生命周期和作用域:

  • a. Static Metadata:
    • 定义: 描述相机设备固有的、不可变的物理特性和能力限制。在相机设备初始化(首次打开或设备启动)时,由 HAL 生成并上报给 FWK。
    • 内容示例:
      • android.lens.info.availableApertures (可用光圈值列表)
      • android.sensor.info.activeArraySize (有效像素阵列尺寸)
      • android.sensor.info.physicalSize (传感器物理尺寸)
      • android.sensor.info.pixelArraySize (像素阵列总尺寸)
      • android.sensor.info.sensitivityRange (ISO 感光度范围)
      • android.sensor.info.exposureTimeRange (曝光时间范围)
      • android.jpeg.maxSize (JPEG 最大支持分辨率)
      • android.request.availableCapabilities (支持的硬件等级和能力,如 RAW, MANUAL_SENSOR, BURST_CAPTURE 等)
      • android.colorCorrection.availableAberrationModes (支持的色差校正模式)
      • android.control.maxRegions (对焦/测光/AWB 区域的最大支持数量)
    • 作用与 Per-Frame Control:
      • 为 APP 和 FWK 提供决策依据。APP 需要知道设备支持哪些分辨率、哪些手动控制模式(如手动曝光)、哪些功能(如 RAW 捕获、光学防抖)才能构建有效的 CaptureRequest。
      • FWK 根据 Static Metadata 来验证 APP 提交的 CaptureRequest 中的参数是否在设备能力范围内。
      • 不参与逐帧变化,它在会话期间是常量,是构建有效动态控制的基础。
      • Static Metadata 其实就是CameraCharacteristics,而CameraCharacteristics在CameraService 启动时,调用CameraProviderManager::initialize(),完成了deviceinfo的初始化,此时metadata 会被赋值给DeviceInfo::mCameraCharacteristics,当上层 Java 层调用 CameraManager.getCameraCharacteristics(cameraId)的时候,其实就把mCameraCharacteristics取出来给CameraCharacteristics。
  • b. Control Metadata (CaptureRequest Metadata):
    • 定义: 由 APP 主动设置并包含在 CaptureRequest 中,用于精确控制下一帧(或一组帧)的捕获和处理行为的参数。这是 APP 表达其拍摄意图的核心手段。
    • 内容示例:
      • android.control.mode (控制模式:OFF, AUTO, USE_SCENE_MODE, USE_TEMPLATE_*)
      • android.control.aeMode (自动曝光模式)
      • android.control.afMode (自动对焦模式)
      • android.control.awbMode (自动白平衡模式)
      • android.control.aeExposureCompensation (曝光补偿值)
      • android.control.aeTargetFpsRange (目标帧率范围)
      • android.control.aeRegions (自动测光区域)
      • android.control.afRegions (自动对焦区域)
      • android.control.awbRegions (自动白平衡区域)
      • android.sensor.exposureTime (手动设置的曝光时间 - 需要 MANUAL_SENSOR 能力)
      • android.sensor.sensitivity (手动设置的 ISO 感光度 - 需要 MANUAL_SENSOR 能力)
      • android.lens.focusDistance (手动设置的对焦距离 - 需要 MANUAL_SENSOR 能力)
      • android.flash.mode (闪光灯模式)
      • android.noiseReduction.mode (降噪模式)
      • android.colorCorrection.mode / android.colorCorrection.transform / android.colorCorrection.gains (色彩校正参数)
      • android.scaler.cropRegion (裁剪区域)
    • 作用与 Per-Frame Control:
      • 这是 Per-Frame Control 的“输入”。APP 可以且鼓励为每一帧设置不同的 Control Metadata,以实现诸如:
        • HDR 连拍:交替设置不同的曝光时间 (android.sensor.exposureTime)。
        • 高速对焦跟踪:持续更新对焦区域 (android.control.afRegions) 或对焦距离 (android.lens.focusDistance)。
        • 平滑曝光调整:逐步改变曝光补偿 (android.control.aeExposureCompensation)。
        • 动态帧率切换:根据场景改变目标帧率 (android.control.aeTargetFpsRange)。
        • 后处理效果切换:逐帧改变降噪强度或色彩风格。
      • HAL 必须尽最大努力满足 CaptureRequest 中指定的 Control Metadata 参数。如果无法完全满足(如请求的曝光时间超出传感器范围),HAL 应使用最接近的有效值并在 Result Metadata 中报告实际使用的值。

CONTROL_AE_MODE 就是tag,只不过是java封装了一层,CONTROL_AF_MODE_CONTINUOUS_PICTURE是tag对应的value

  • c. Dynamic Metadata (CaptureResult Metadata):
    • 定义: 由 HAL 填充并包含在 CaptureResult 中,用于反馈与 特定帧 捕获和处理结果相关的实时状态和实际使用的参数。它描述了 HAL 执行完对应 CaptureRequest 后的实际结果。
    • 内容示例:
      • android.sensor.timestamp (图像传感器开始曝光的精确时间戳 - 纳秒级)
      • android.sensor.frameDuration (该帧的实际曝光+读取时间)
      • android.sensor.exposureTime (该帧实际使用的曝光时间)
      • android.sensor.sensitivity (该帧实际使用的 ISO 感光度)
      • android.lens.focusDistance (该帧实际使用的对焦距离)
      • android.lens.focalLength (该帧使用的实际焦距 - 变焦镜头)
      • android.lens.aperture (该帧使用的实际光圈值 - 可变光圈镜头)
      • android.lens.state (镜头移动状态,如 STATIONARY, MOVING)
      • android.control.aeState (自动曝光当前状态:INACTIVE, SEARCHING, CONVERGED, LOCKED, FLASH_REQUIRED, PRECAPTURE)
      • android.control.afState (自动对焦当前状态)
      • android.control.awbState (自动白平衡当前状态)
      • android.statistics.lensShadingMapMode (实际使用的镜头阴影校正图模式)
      • android.statistics.sceneFlicker (检测到的场景闪烁频率)
      • android.statistics.faces (检测到的人脸信息)
      • android.tonemap.curve (实际应用的颜色映射曲线)
      • 陀螺仪、加速度计等传感器在该帧曝光时刻的数据(用于高级防抖或计算)
    • 作用与 Per-Frame Control:
      • 这是 Per-Frame Control 的“输出”和“反馈”。它为 APP 提供了:
        • 实际执行结果: 确认 HAL 实际使用了哪些参数值(可能与 Request 略有不同)。
        • 实时状态监控: 了解 3A (AE/AF/AWB) 算法当前的运行状态(如是否已收敛、是否在搜索中、是否需要闪光灯)。
        • 精确的时间关联: 高精度时间戳 (android.sensor.timestamp) 是逐帧控制的关键,它允许 APP 将图像帧与手机运动传感器(陀螺仪、加速度计)在同一时刻的数据精确对齐,用于高级计算摄影(如计算光学防抖补偿、多帧合成时的运动估计)。
        • 决策依据: APP 可以根据前一帧的 Dynamic Metadata(尤其是 3A 状态)来智能地调整下一帧的 Control Metadata,形成一个闭环控制。例如,如果 AE 状态是 SEARCHING,APP 可能暂时不进行 HDR 连拍;如果 AF 状态是 FOCUSED,APP 可以锁定对焦。

3. Per-Frame Control 的工作流程(结合 Metadata)

  1. APP 查询 Static Metadata: APP 启动时或打开相机前,通过 FWK 获取设备的 Static Metadata,了解其能力。
  2. APP 创建 CaptureRequest:
    1. APP 创建一个新的 CaptureRequest 对象。
    2. APP 设置 Control Metadata (request): 根据当前拍摄意图(自动、手动、HDR、人像等)和从 Static Metadata 了解到的设备能力,设置所需的参数(曝光模式、ISO、对焦区域、裁剪、处理参数等)。关键:APP 可以为 每一帧 设置不同的 Control Metadata。
    3. APP 指定该 Request 的输出目标(Surface),如预览 Surface、拍照 Surface、RAW Surface。
  3. APP 提交 Request 给 FWK: APP 将构建好的 CaptureRequest 提交给相机框架 (FWK)。
  4. FWK 处理 Request:
    1. FWK 进行权限检查、参数校验(参考 Static Metadata)、资源管理。
    2. FWK 可能对 Request 进行修改或补充(例如,确保必要的 Tag 被设置,或应用全局设置)。
    3. FWK 将 Request(包含 Control Metadata 和输出目标信息)加入待处理队列。
  5. FWK 传递 Request 给 HAL: FWK 从队列中取出 Request,将其(主要是 Control Metadata 和输出 Buffer 信息)传递给 Camera HAL。
  6. HAL 执行 Request:
    1. HAL 解析 CaptureRequest 中的 Control Metadata
    2. HAL 驱动相机硬件(传感器、镜头、ISP)按照 Control Metadata 的要求进行单帧图像的捕获(曝光、对焦、变焦等)。
    3. HAL 将捕获到的图像数据(RAW 或处理后的 YUV)写入到 Request 指定的输出 Surface 对应的 Buffer 中。
    4. HAL 生成 CaptureResult
      1. 收集该帧捕获过程中的实际使用的参数(可能与 Request 不同)。
      2. 收集该帧相关的动态状态信息(3A 状态、时间戳、传感器数据等)。
      3. 将以上信息填充到 CaptureResultDynamic Metadata 部分。
      4. (可选)HAL 可以包含一些额外的状态信息。
  7. HAL 返回 Result 给 FWK: HAL 将包含图像 Buffer 的句柄和填充好的 CaptureResult (包含 Dynamic Metadata) 返回给 FWK。
  8. FWK 处理 Result:
    1. FWK 将图像 Buffer 分发到对应的 APP Surface。
    2. FWK 可能对 CaptureResult 进行补充(添加框架相关的信息或状态)。
  9. FWK 传递 Result 给 APP: FWK 将最终的 CaptureResult (包含 Dynamic Metadata) 传递给 APP。
  10. APP 处理 Result:
    1. APP 接收到图像数据,进行显示(预览)或保存(拍照)。
    2. APP 解析 CaptureResult 中的 Dynamic Metadata
      1. 获取实际参数,确认执行效果。
      2. 监控 3A 状态 (aeState, afState, awbState)。
      3. 获取关键的高精度时间戳 (sensor.timestamp)
      4. 获取传感器数据(用于防抖或多帧合成)。
    3. 基于 Dynamic Metadata 进行闭环决策: APP 分析当前帧的结果和状态,下一帧后续帧CaptureRequest 设置新的、可能不同的 Control Metadata,以实现更复杂的功能(如触发 HDR 连拍、调整对焦区域、平滑过渡曝光补偿)。这就是 Per-Frame Control 的精髓所在!
  11. 循环: APP 创建并提交新的 CaptureRequest,流程回到步骤 2。这个过程持续进行,APP 通过不断调整 Control Metadata 并观察 Dynamic Metadata 反馈,实现对相机行为的细粒度、实时的逐帧控制。

4.帧控制的伪代码

// 1. 打开相机后,创建一个 CaptureRequest.Builder
CaptureRequest.Builder builder =
        cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);


// 添加预览输出 Surface
builder.addTarget(previewSurface);


// 2. 连续下发不同的 Request,模拟 Per-Frame Control
List<CaptureRequest> burstRequests = new ArrayList<>();


// 帧 1: 自动曝光 + 连续自动对焦
builder.set(CaptureRequest.CONTROL_AE_MODE,
            CaptureRequest.CONTROL_AE_MODE_ON);
builder.set(CaptureRequest.CONTROL_AF_MODE,
            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
burstRequests.add(builder.build());


// 帧 2: 固定曝光时间 10ms,ISO 200,手动对焦
builder.set(CaptureRequest.CONTROL_MODE,
            CaptureRequest.CONTROL_MODE_OFF); // 关闭 3A 自动
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 10_000_000L); // 10ms
builder.set(CaptureRequest.SENSOR_SENSITIVITY, 200);           // ISO 200
builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.3f);         // 对焦到 0.3 米
burstRequests.add(builder.build());


// 帧 3: 曝光时间 30ms,ISO 800,自动对焦
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 30_000_000L); // 30ms
builder.set(CaptureRequest.SENSOR_SENSITIVITY, 800);           // ISO 800
builder.set(CaptureRequest.CONTROL_AF_MODE,
            CaptureRequest.CONTROL_AF_MODE_AUTO);
burstRequests.add(builder.build());


// 3. 一次性发给 Camera HAL,逐帧执行
captureSession.captureBurst(
        burstRequests,
        new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureCompleted(CameraCaptureSession session,
                                           CaptureRequest request,
                                           TotalCaptureResult result) {
                // 每一帧都会回调对应的 Dynamic Metadata
                long exposureTime = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
                int iso = result.get(CaptureResult.SENSOR_SENSITIVITY);
                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
                Log.d("PerFrame", "Frame done: exposure=" +
                        exposureTime + " iso=" + iso + " af=" + afState);
            }
        },
        null
);
// HAL 接口:每来一帧,都会调用一次
int process_capture_request(camera3_device *device,
                            camera3_capture_request_t *request) {
    // 取出这帧的 metadata(控制参数)
    const camera_metadata_t *settings = request->settings;
    CameraMetadata ctrlMeta(settings);


    int64_t exposureTime = 0;
    int32_t sensitivity = 0;
    int32_t afMode = 0;


    // 1. 解析 AE/曝光控制
    if (ctrlMeta.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
        exposureTime = ctrlMeta.find(ANDROID_SENSOR_EXPOSURE_TIME).data.i64[0];
        applyExposure(exposureTime);  // 应用到 ISP/传感器驱动
    }


    // 2. 解析 ISO
    if (ctrlMeta.exists(ANDROID_SENSOR_SENSITIVITY)) {
        sensitivity = ctrlMeta.find(ANDROID_SENSOR_SENSITIVITY).data.i32[0];
        applyISO(sensitivity);
    }


    // 3. 解析 AF 模式
    if (ctrlMeta.exists(ANDROID_CONTROL_AF_MODE)) {
        afMode = ctrlMeta.find(ANDROID_CONTROL_AF_MODE).data.i32[0];
        applyAfMode(afMode); // 设置对焦算法状态机
    }


    // 4. 实际驱动 sensor 输出一帧图像
    BufferHandle buffer = request->output_buffers[0];
    captureOneFrame(buffer, exposureTime, sensitivity, afMode);


    // 5. 构造 Dynamic Metadata,反馈给上层
    CameraMetadata result;
    result.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1);
    result.update(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1);
    result.update(ANDROID_CONTROL_AF_MODE, &afMode, 1);


    camera3_capture_result captureResult;
    memset(&captureResult, 0, sizeof(captureResult));
    captureResult.frame_number = request->frame_number;
    captureResult.result = result.release();
    captureResult.num_output_buffers = 1;
    captureResult.output_buffers = request->output_buffers;


    // 回调给 Framework
    callbacks->process_capture_result(callbacks, &captureResult);


    return 0;
}

总结

Camera HAL3 的 Metadata 机制是一个强大、标准化的信息交换系统。通过将 Metadata 明确划分为 Static(设备能力)、Control(逐帧输入/意图)和 Dynamic(逐帧输出/结果/反馈)三类,它完美地支撑了 Per-Frame Control 的核心思想:

  1. Static Metadata 提供基础,定义可能性的边界。
  2. Control Metadata 赋予 APP 对每一帧参数的精确控制权,实现灵活多变的拍摄策略。
  3. Dynamic Metadata 提供每一帧执行后的真实反馈和精确时空信息(尤其是时间戳),使得 APP 能够基于实际结果进行闭环决策并执行高级计算摄影算法。

Metadata 作为贯穿 APP、FWK、HAL 三层的结构化数据总线,是 HAL3 相较于早期 HAL 实现更强大功能和更优性能的关键架构创新。它使得现代智能手机上的复杂计算摄影功能(如 HDR+、人像模式、超级夜景、动态帧率切换)得以高效、灵活地实现。

一个完整的Metadata的结构如下图所示,包含了vendortag、values和type

值得注意的是TAG 是 Metadata 的索引基石​:通过 (Section + 子索引)(其实表示了这个Metadata想要管理什么) 唯一标识参数,映射到Metadata内存中的 Entry 存储单元

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值